.. _api_upload_and_run: # Uploading a file and running a model This example uploads a new input file to the Platform, then runs a model that uses the new file as input data. It uses the :ref:`getting-started` tutorial project - if you have not worked through that tutorial yet, it is worth doing so first, to familiarize yourself with running the model in the web interface. As with the other :ref:`api_examples`, this uses `curl` and assumes you already have a personal access token, as described in :ref:`api_authentication`. :ref:`Setup an environment variable ` called `RISKSCAPE_TOKEN` with your token, e.g. ```none read -s -p "Access token: " RISKSCAPE_TOKEN ``` Your Platform account may not have access permissions to perform all operations in this example, so for simplicity you could replace the `RISKSCAPE_PROJECT` environment variable with a project you are admin or editor for, i.e. ```none export RISKSCAPE_PROJECT=riskcape/example/getting-started ``` ## The model we are running The `Total-exposed` model in the getting started project takes an exposure layer as one of its parameters, `exposure_layer`. In the tutorial, this parameter is set to `Buildings_SE_Upolu.gpkg`, a file already sitting in the project's storage. Rather than upload a brand new file, this example replaces `Buildings_SE_Upolu.gpkg` with a copy of itself, so that you can follow along without needing any building data of your own. If you have your own GeoPackage or GeoJSON file with the same attributes, feel free to use that instead. .. tip:: Model parameters like ``exposure_layer`` refer to a file already sitting in project or personal storage. So uploading a file and running a model are therefore two separate API requests, done one after the other. ## Uploading an input file In the API, files are located under a project's `files` resource. Upload a file to a path in project storage with a `PUT` request, using the file's own bytes as the request body: ```none curl -s -u TOKEN:$RISKSCAPE_TOKEN \ -X PUT \ --data-binary @Buildings_SE_Upolu.gpkg \ https://riskscape.nz/api/projects/by-full-slug/$RISKSCAPE_PROJECT/files/by-path/Buildings_SE_Upolu.gpkg ``` A successful upload returns `204 No Content`, with no response body. .. note:: You can set a ``Content-Type`` header to tell RiskScape the file's media type. If you leave it out, or send a generic type like ``application/octet-stream``, RiskScape works out the media type from the file's extension instead, which is what happens above. ## Running the model In the API, model runs are located under a project's `runs` resource. Send a `POST` request to `/runs/new`, with the model's id and its parameters as a JSON body. Each parameter needs a `label` (a human-friendly name for it, used for display purposes) as well as the `value` the model will actually use: ```none curl -s -u TOKEN:$RISKSCAPE_TOKEN \ -X POST \ -H "Content-Type: application/json" \ -d @body.json \ https://riskscape.nz/api/projects/by-full-slug/$RISKSCAPE_PROJECT/runs/new ``` where `body.json` contains: ```none { "externalModelId": "Total-exposed", "managed": true, "parameters": { "exposure_layer": { "label": "Exposure layer", "value": "Buildings_SE_Upolu.gpkg" } } } ``` .. note:: The parameters in the JSON body are what will appear in the Platform's model run listing. If parameters are omitted, then the default value for that parameter will be used, but this will not be reported in the Platform's model run listing. The response is the new model run, as JSON, including its `id` and a `state` of `CREATED` or `RUNNING`, e.g. ```none { "id": 1234, "externalModelId": "Total-exposed", "state": "RUNNING", ... } ``` ## Waiting for the run to finish Running a model happens asynchronously in the background, so you need to poll the model run API until it finishes. Use the `id` from the response above to fetch the run's current state from `/api/model-runs/by-id/{id}`: ```none curl -s -u TOKEN:$RISKSCAPE_TOKEN \ https://riskscape.nz/api/model-runs/by-id/1234 ``` Keep polling this URL every few seconds until `state` is `COMPLETE` (or `FAILED`, if something went wrong). The response also includes a `finished` field, which is `true` once the run has stopped, whether it succeeded or not. ## Getting the results Once the run is `COMPLETE`, its `outputs` list names each result file, e.g. `summary`. You can download an output's content from `/api/model-runs/by-id/{id}/output/{name}/download`: ```none curl -s -u TOKEN:$RISKSCAPE_TOKEN \ https://riskscape.nz/api/model-runs/by-id/1234/output/summary/download \ -o summary.csv ``` .. note:: Leaving off ``/download`` returns the output's metadata as JSON (its name, media type and size) instead of the file itself. You should see the same `summary` results you would get from running the model in the web interface, showing the number of exposed buildings per region.