|
| 1 | +""" |
| 2 | +Handles interfacing with the plots analysis api v1 documented at: |
| 3 | +https://app.picterra.ch/public/apidocs/plots_analysis/v1/ |
| 4 | +
|
| 5 | +Note that that Plots Analysis Platform is a separate product from the Detector platform and so |
| 6 | +an API key which is valid for one may encounter permissions issues if used with the other |
| 7 | +""" |
| 8 | +import datetime |
| 9 | +from typing import Literal |
| 10 | + |
| 11 | +import requests |
| 12 | +from requests.exceptions import RequestException |
| 13 | + |
| 14 | +from picterra.base_client import APIError, BaseAPIClient |
| 15 | + |
| 16 | +AnalysisMethodology = Literal["eudr_cocoa", "eudr_soy"] |
| 17 | + |
| 18 | + |
| 19 | +class PlotsAnalysisPlatformClient(BaseAPIClient): |
| 20 | + def __init__(self, **kwargs): |
| 21 | + super().__init__("public/api/plots_analysis/v1/", **kwargs) |
| 22 | + |
| 23 | + def batch_analyze_plots(self, plots_geometries_filename: str, methodology: AnalysisMethodology, assessment_date: datetime.datetime): |
| 24 | + """ |
| 25 | + Runs the specified methodology against the plot geometries stored in the provided file and |
| 26 | + returns the analysis results. |
| 27 | +
|
| 28 | + Args: |
| 29 | + - plots_geometries_filename: Path to a file containing the geometries of the plots to run the |
| 30 | + analysis against. |
| 31 | + - methodology: which analysis to run. |
| 32 | + - assessment_date: the point in time at which the analysis should be evaluated. |
| 33 | +
|
| 34 | + Returns: the analysis results as a dict. |
| 35 | + """ |
| 36 | + # Get an upload URL and analysis ID |
| 37 | + resp = self.sess.post(self._full_url("batch_analysis/upload/")) |
| 38 | + try: |
| 39 | + resp.raise_for_status() |
| 40 | + except RequestException as err: |
| 41 | + raise APIError( |
| 42 | + f"Failure obtaining an upload url and plots analysis ID: {err}" |
| 43 | + ) |
| 44 | + |
| 45 | + analysis_id = resp.json()["analysis_id"] |
| 46 | + upload_url = resp.json()["upload_url"] |
| 47 | + |
| 48 | + # Upload the provided file |
| 49 | + with open(plots_geometries_filename, "rb") as fh: |
| 50 | + resp = requests.put(upload_url, data=fh.read()) |
| 51 | + try: |
| 52 | + resp.raise_for_status() |
| 53 | + except RequestException as err: |
| 54 | + raise APIError(f"Failure uploading plots file for analysis: {err}") |
| 55 | + |
| 56 | + # Start the analysis |
| 57 | + data = {"methodology": methodology, "assessment_date": assessment_date.isoformat()} |
| 58 | + resp = self.sess.post( |
| 59 | + self._full_url(f"batch_analysis/start/{analysis_id}/"), data=data |
| 60 | + ) |
| 61 | + try: |
| 62 | + resp.raise_for_status() |
| 63 | + except RequestException as err: |
| 64 | + raise APIError(f"Couldn't start analysis for id: {analysis_id}: {err}") |
| 65 | + |
| 66 | + # Wait for the operation to succeed |
| 67 | + op_result = self._wait_until_operation_completes(resp.json()) |
| 68 | + download_url = op_result["results"]["download_url"] |
| 69 | + resp = requests.get(download_url) |
| 70 | + try: |
| 71 | + resp.raise_for_status() |
| 72 | + except RequestException as err: |
| 73 | + raise APIError( |
| 74 | + f"Failure to download results file from operation id {op_result['id']}: {err}" |
| 75 | + ) |
| 76 | + results = resp.json() |
| 77 | + |
| 78 | + return results |
0 commit comments