RosaeNLG Lambda functions

This is the documentation for 3.1.0 version, which is not the latest version. Consider upgrading to 4.3.1.

RosaeNLG is hosted freemium on Rapid API. But you can run your own RosaeNLG API:

  1. either install your own Node.js Server

  2. or deploy some Lambda functions on AWS

Swagger is here.

Pros & Cons

Compared to the Node.js Server:

  • Pros

    • when hosting on AWS, Lambda will probably be cheaper

    • you can deploy only some languages

    • auto scaling etc.

  • Cons

    • a little less features (see below)

    • requires more expertise to deploy

    • backend is always S3 (on node version you can use a disk)

Missing features compared to Node.js version

The following features are available in the Node.js Server but not in the lambda version:

  • ability to compile and render in the same API call (specific endpoint in the node API)

  • simplified syntax <…​> is not available in Lambda version

Authentication

Authentication can be made either:

  • Using a JWT token (Authorization: Bearer …​). Use for instance auth0. User ID is taken for sub.

  • Using a secret key (Authorization: …​). Will be checked against RapidAPI-Proxy-Secret secret in SSM. User ID is taken in X-RapidAPI-User header.

Deployment guide

To be completed

Some auth features are related to RapidAPI auth system and you will have to adapt that if you don’t go through RapidAPI.
  • checkout the RosaeNLG mono repo (is not published as an npm package)

  • you must be able to compile test etc., see Developer documentation

  • lambda code is in rosaenlg-lambda package

  • specific domain name:

    • create a serverless-props.json file with a domainName entry

    • or just remove serverless-domain-manager plugin in serverless.yml to disable custom domain

  • RapidAPI secret key:

    • create a serverless-props.json file with a ssmKey entry; this key must contain the X-RapidAPI-Proxy-Secret secret

    • also change RapidAPI-Proxy-Secret in helper.ts

  • you may configure serverless.yml:

    • service or stackName

    • change S3 bucket names

    • you might have to change memory settings if your templates are large

    • only deploy languages that you will use

  • deploy using serverless deploy

  • test, see example below

You can use stages to separate stack and buckets between dev and prod.

Sample serverless-props.json file:

{
  "dev": {
    "domainName": "rosaenlg-dev.yourdomain.com",
    "ssmKey": "arn:aws:ssm:REGION:YOUR_ID:parameter/THE_KEY",
    "tokenIssuer": ...,
    "jwksUri": ...,
    "audience": ...,
    "sharedUser": "shared user ID, remove line to disable feature"
  },
  "prod": {
    "domainName": "rosaenlg-prod.yourdomain.com",
    "ssmKey": "arn:aws:ssm:REGION:YOUR_ID:parameter/THE_KEY"
  }
}

Testing

Register a template:

curl --location --request PUT 'https://YOUR_AWS_ENDPOINT/dev/templates/fr_FR' \
--header 'Content-Type: application/json' \
--header 'X-RapidAPI-Proxy-Secret: YOUR_SECRET_RAPIDAPI_KEY_HERE' \
--data-raw '{
  "templateId": "chanson",
  "src": {
    "entryTemplate": "chanson.pug",
    "compileInfo": {
      "compileDebug": false,
      "language": "fr_FR"
    },
    "templates": {
      "chanson.pug": "p\n  | il #[+verb(getAnonMS(), {verb: '\''chanter'\'', tense:'\''FUTUR'\''} )]\n  | \"#{chanson.nom}\"\n  | de #{chanson.auteur}\n"
    },
    "autotest": {
      "activate": true,
      "input": {
        "language": "fr_FR",
        "chanson": {
          "auteur": "Édith Piaf",
          "nom": "Non, je ne regrette rien"
        }
      },
      "expected": [
        "Il chantera \"Non, je ne regrette rien\" d'\''Édith Piaf"
      ]
    }
  }
}'

You should get:

{
  "templateId": "chanson",
  "templateSha1": "3810225efaa3aa43e231c140a081c420ac29860d",
  "ms":...
}

Render a template:

curl --location --request POST 'https://YOUR_AWS_ENDPOINT/dev/templates/fr_FR/chanson/3810225efaa3aa43e231c140a081c420ac29860d' \
--header 'Content-Type: application/json' \
--header 'X-RapidAPI-Proxy-Secret: YOUR_SECRET_RAPIDAPI_KEY_HERE' \
--data-raw '{
    "language": "fr_FR",
    "chanson": {
        "auteur": "Jacques Brel",
        "nom": "Amsterdam"
    }
}'

You should get:

{
  "renderedText": "<p>Il chantera \"Amsterdam\" de Jacques Brel</p>",
  "renderOptions": {
      "language": "fr_FR"
  },
  "ms": ...
}