Skip to content

Lambda function to convert the Mobi API response to a format which Airbyte can handle

License

Notifications You must be signed in to change notification settings

DalgoT4D/shofco-mobi-water

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 

Repository files navigation

Background and Motivation

We invoke two APIs at Mobi's end:

(API-1) https://api.mobiwaternet.co.ke/monitoring/v1/flowdevices/flowDeviceAccess/

which returns JSON, and then for each flowDeviceId in this response we invoke

(API-2) https://api.mobiwaternet.co.ke/monitoring/v1/flowdevices/flowDeviceAnalytics/consumption/{flow_device_id}?toDate={to_date}&fromDate={from_date}

API-2 returns a number, but as text instead of in a JSON object. Airbyte can convert a plaintext response to JSON (https://docs.airbyte.com/connector-development/connector-builder-ui/record-processing#iterable) but only if the Content-Type is set to text/plain or text/html. Unfortunately Mobi's API returns a context type of application/json and so Airbyte does not do this.

Response formats

API-1 returns a JSON object having the schema

flowDeviceName: string
flowDeviceLocation: string
flowDeviceDescription: string
flowDevicePulseRate: float
flowDeviceSize: float
deviceType: string
deviceId: integer
consumptionThreshold: float
organization:
  organizationId: integer
  organizationName: string
  organizationEmail: string
  organizationPhoneNo: string
  organizationCallbackUrl: string
flowDeviceId: integer
dailyConsumption: float
lastReceivedFlowData:
  measuredFlowRate: float
  predictedFlowRate: float
  acceptedFlowRate: float
  measuredConsumption: float
  predictedConsumption: float
  acceptedConsumption: float
  rawPulses: float
  measuredAt: string
  measuredFrom: string
  flowDeviceState: string
  notificationState: string
  flowDataId: integer
hardwareState: string

API-2 returns just text i.e.

r = requests.get("https://api.mobiwaternet.co.ke/monitoring/v1/flowdevices/flowDeviceAnalytics/consumption/268", 
                 params={"fromDate": "2024-01-01 00:00:00", "toDate": "2024-01-01 01:00:00"},
                 headers=headers)
# r.text == '0.0'

Solution

Write a small API of our own (API-C) to wrap the response of the API-2 into a JSON object and call this from Airbyte's no-code connector.

Airbyte's connector needs to

  1. Invoke API-1
  2. Loop through the response
  3. For each element, invoke API-2 on that flowDeviceId

Since each connector has only one base URL, our API-C wraps API-1 as well as API-2. The response from API-1 is forwarded as received, and the response from API-2 is wrapped into the object {"value": string, "flow_device_id": string}

Implementation

A function on AWS Lambda, with an HTTP endpoint for invocation. The caller must pass a Bearer token to authenticate the request. The lambda compares this incoming token with the token saved in the environment variable DALGO_BEARER_TOKEN. The lambda then calls the Mobi API using the MOBI_BEARER_TOKEN.

The lambda is invoked by sendin a POST request to the endpoint https://***********.lambda-url.ap-south-1.on.aws/ with the correct Authorization header. The response is always JSON.

Endpoint for API-1: /user-meter Endpoint for API-2: /meter-consumption?flow_device_id=XXX[&toDate=XXX&fromDate=XXX]

If toDate is not provided it defaults to the current date. If fromDate is not provided it defaults to the previous date.

About

Lambda function to convert the Mobi API response to a format which Airbyte can handle

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages