5 Developer notes
This page contains notes for DemoLand developers. You should not need to read this unless you are actively working on the codebase, or maintaining any of the associated systems.
5.1 API specification
The calculation of indicators for custom scenarios in the web app relies on an API. Right now, the web app uses an API which is hosted as an Azure Function.
In particular, the function must accept a POST body that looks like this. Only output areas which are changed relative to the baseline need to be included in the inner JSON object:
{
"model_identifier": string,
"scenario_json": {
output_area_name: {
"signature_type": int | null,
"job": float | null,
"use": float | null,
"greenspace": float | null
},
...
}
}
Upon success, this must return a JSON response with the following format (all output areas must be included):
{
output_area_name: {
"air_quality": float,
"house_price": float,
"job_accessibility": float,
"greenspace_accessibility": float,
"signature_type": int
},
...
}
The function demoland_engine.api.scenario_calc()
obeys this schema, and both the FastAPI and the Azure Functions apps simply wrap this function.
5.2 FastAPI, local
Note: If you are running the web app in development mode and want to use the ‘Local REST API’ for custom scenario calculation, this is the section to follow.
One way to run the API is to run it locally or over Docker. To do this, there is a FastAPI app located at api/main.py
. First make sure you have the optional dependencies for the FastAPI app installed. Go to the top-level directory of the repo and run
python -m pip install .[api]
The [api]
instructs pip
to install the optional dependencies, which can be seen in pyproject.toml
.
Then, again from the top-level directory, run:
uvicorn main:app --app-dir api --port 5178
You should now be able to test the API using:
curl http://localhost:5178/api/scenario -X POST -d "{\"scenario_json\": {}, \"model_identifier\": \"tyne_and_wear\"}" -v -H 'Content-Type: application/json'
(Note that the Content-Type
header is mandatory, otherwise FastAPI doesn’t accept the input.)
5.3 FastAPI, over Docker
Dockerfile.api
provides the specification for running the FastAPI app over Docker. Simply do:
docker build . -f Dockerfile.api -t demoland-api
docker run -it demoland-api
The Dockerfile is configured to expose the API on port 80 (which is the default port for HTTP), so you can omit the port number when testing:
curl http://localhost/api/scenario -X POST -d "{\"scenario_json\": {}, \"model_identifier\": \"tyne_and_wear\"}" -v -H 'Content-Type: application/json'
5.4 Azure Functions
Note: There is a GitHub Action on the demoland-engine
repository which automatically deploys the Azure Function instance from the main branch. You should not need to manually update the Azure Functions deployment, but the steps are kept here in case you need to troubleshoot.
To deploy a new version of the Azure function, make sure you are a member of the “Land Use Indicator” Azure subscription (the subscription ID is 86307bb0-6d16-4077-b1f7-939370d5289a
). If you are not, get Dani to add you.
Then, follow these instructions:
Log in to Azure. This will open a browser window where you can log in with your Microsoft account.
az login
Set your active subscription to the one above:
az account set -s 86307bb0-6d16-4077-b1f7-939370d5289a
Install the Azure Functions Core Tools. The following Homebrew command works on macOS; for other operating systems, refer to the Azure docs
brew tap azure/functions brew install azure-functions-core-tools@4
Clone the
demoland-engine
repository (if you don’t already have it), andcd
to the top level of thedemoland-engine
repository. Check that the filesfunction_app.py
andlocal.settings.json
are present in the top-level directory.To test the function locally, run:
func start
You should then be able to access the API at
http://localhost:7071/api/scenario
. For example, you can test it using the following command, which asks it to calculate the baseline indicators (an empty scenario means no changes relative to the baseline):curl http://localhost:7071/api/scenario -X POST -d "{\"scenario_json\": {}, \"model_identifier\": \"tyne_and_wear\"}" -v
To deploy it to Azure, run the following, which will take a few minutes:
func azure functionapp publish demolandapi
Test it with:
curl https://demolandapi.azurewebsites.net/api/scenario -X POST -d "{\"scenario_json\": {}, \"model_identifier\": \"tyne_and_wear\"}" -v