Step 2: Compiling and running the TypeScript API

Now that you have the generated TypeScript code in the src/gen folder, let’s use it to access the platform.

As a first test, you will query all data sets that exist in your account.

Step 2.0 (optional): Include the code generation in the package.json file

You can add the command used to generate the TypeScript code from the OpenAPI schema to your package.json file.

For example:

package.json
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
{
  "scripts": {
    "generate-code": "mkdir -p src/gen && . $HOME/.sdkman/bin/sdkman-init.sh && sdk env install && sdk env && npx openapi-generator-cli generate -g typescript-node --additional-properties=typescriptThreePlus=true --global-property=skipFormModel=false -o src/gen -i openapi.json"
  },
  "dependencies": {
    "@openapitools/openapi-generator-cli": "2.5.1",
    "axios": "0.26.1",
    "form-data": "2.5.1",
    "request": "2.88.2"
  },
  "devDependencies": {
    "@tsconfig/recommended": "1.0.1",
    "@types/request": "2.48.8",
    "typescript": "4.7.4"
  }
}

If you need to re-generate the code, you can now just run

npm run-script generate-code

Note that the axios and form-data dependencies that are shown in the package.json file above are only needed in a specific scenario.

Step 2.1: Create a tsconfig.json file

In order to compile the generated TypeScript code and the actual script, you’ll need a tsconfig.json file.

Create a tsconfig.json with the following contents:

tsconfig.json
1
2
3
4
5
6
7
{
  "extends": "@tsconfig/recommended/tsconfig.json",
  "compilerOptions": {
    "rootDir": "./src",
    "outDir": "./dist"
  }
}

This specifies that the source files are located in the src directory, and that the compiler should place the output .js files in the dist folder.

Also note the "extends": "@tsconfig/recommended/tsconfig.json" part which tells TypeScript that our configuration is an extension of a base configuration file. This base configuration file was installed previously when we installed the npm packages on which we’re going to depend.

Double check if your setup is working by running:

npx tsc

This should generate a dist folder containing .js files:

dist/gen
 |_ api.js
 |_ api
 |  |_ api.js
 |  |_ ... (more *.js files)
 |_ model
    |_ createGeoJSONLayerRequest.js
    |_ ... (more *.js files)

Step 2.2: Obtaining an API username and password

The first query you should do with the xyzt.ai platform is to authenticate yourself and obtain a JWT token that will subsequently be used to securely access the platform.

For this, you need to authenticate yourself using an API username and password.

Navigate to the user management section of the platform. At the bottom of this page you can generate a new API user.

Copy the username and password for your reference.

Not all users have rights to generate API users.

If you don’t see the ability to create an API user, you probably have insufficient admin rights on the xyzt.ai platform. Or, your account does not allow for API access.

In the first case, reach out to your xyzt.ai account owner, or, as in the second case, contact us at support@xyzt.ai.

Step 2.3 Your first platform REST query

With the API user credentials, you can now use the generated TypeScript code to authenticate with the platform and start using the REST API.

In this first example, you will query the existing data sets in the platform.

Add following App.ts file to your src folder that contains our script:

App.ts
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import {
  AuthenticationJWTTokenApi,
  DataSetsApi,
  HttpBearerAuth,
} from "./gen/api";

const userName = "replace with your API user name";
const password = "replace with your API user password";

async function getJWTToken() {
  const authenticationApi = new AuthenticationJWTTokenApi();

  return await authenticationApi
    .obtainToken({
      userName: userName,
      password: password,
    })
    .then((r) => {
      return r.body.jwtToken;
    })
    .catch((reason) => {
      console.log(reason);
      return null;
    });
}

getJWTToken().then(async (token) => {
  console.log("Got access token : " + token);

  if (token == null) {
    return;
  }

  //Use the obtained JWT token to create an authentication object
  const authentication = new HttpBearerAuth();
  authentication.accessToken = token;

  const dataSetsApi = new DataSetsApi();
  //Make sure all requests to the server use the JWT token
  dataSetsApi.setDefaultAuthentication(authentication);

  //Query for all the datasets
  const dataSets = (await dataSetsApi.getAllDataSets()).body;
  console.log(dataSets);
});

Do not forget to edit the userName and password variables at the top of the file with the ones obtained after creating the API user.

The code is self-explanatory: it obtains a JWT token using the API username and password. It then uses the DataSetsApi (configured with an Authentication that holds the JWT token for authentication) to query all available data sets. Afterward, the resulting array is printed on the console.

The JWT token has a limited lifetime, you should refresh it.

JWT tokens remain valid for 15 minutes. If your script runs longer, you will have to refresh the token.

To run the script, compile it and run it:

npx tsc
node dist/App.js

If successful, this should print the obtained JWT token and a JSON output of the available data sets in the platform.

The obtained dataSets constant is an array, where each prints on the console like this:

PublicDataSetDTO {
    id: '95c78f24-0326-438a-86e2-f0da0e8010f8',
    name: 'Sample Data: New York Yellow taxi',
    description: '',
    batches: [ 'XYZT_AI_default' ],
    minimumTime" 1230768000,
    maximumTime: 1262300400,
    spatialBounds: {
      longitude: -74.56060574157071,
      latitude: 40.237267244602684,
      width: 1.4640249502781444,
      height: 1.2784242093559612
    },
    visualizationModes: [ 'GRIDDED' ],
    owned: true,
    state: 'IDLE',
    type: 'STATIC_GEOJSON',
    repositoryType: 'DATA_SET'
}

The data set entry contains properties id, name, etc. The id property is particularly important as all resources (including projects, data sets, etc.) are referenced by a unique identifier and not by the name that was provided for example when creating the project or data set.

In the next step of this tutorial, you will use this id property to add an existing data set to a new project.

Next part