This page is to avoid cluttering the main blog with a documentation post every time I add functionality to the api.

The API’s base URL is https://api.aawadia.dev

**[NEW]** Object detection API now live!

Date: 2022-08-14 16:43:23

I have been studying machine learning for a while now and have been working on how I can bring model inferences to the JVM i.e. not have to use Python. This API provides an HTTP interface to an object detection model, simply stated you give it an image and it returns the classes [things in the image], the probability [accuracy], and the bounding boxes x and y coordinates.

There is one POST endpoint at https://api.aawadia.dev/ml/v1/object-detect

The request should upload a file that is the image on which the analysis should run on. The max image size allowed is 5MB.

Example of a curl request that sends an image file from the local filesystem

1
2
3
4
5
curl -v --request POST \
--url https://api.aawadia.dev/ml/v1/object-detect \
--header 'Accept-Encoding: gzip' \
--header 'Content-Type: multipart/form-data' \
--form [email protected]/path/to/image.png

The response is the top 10 [up to 10] classes detected in the following format

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
{
"result": [
{
"classLabel": "car",
"probability": 0.8407365,
"xmax": 0.8965405,
"xmin": 0.85874724,
"ymax": 0.5887568,
"ymin": 0.544538
},
{
"classLabel": "car",
"probability": 0.820495,
"xmax": 0.9454968,
"xmin": 0.90837324,
"ymax": 0.58662194,
"ymin": 0.5463044
},
{
"classLabel": "traffic light",
"probability": 0.79108596,
"xmax": 0.98530835,
"xmin": 0.97503823,
"ymax": 0.48037714,
"ymin": 0.44478416
},
{
"classLabel": "person",
"probability": 0.54140717,
"xmax": 0.8512671,
"xmin": 0.8202702,
"ymax": 0.6288285,
"ymin": 0.56220734
}
]
}

SqlParser API now live!

Date: 2022-07-02 11:43:23

I am working on a project that requires parsing and processing sql queries. To evaluate a sql query first it needs to be parsed out - this api provides the ability to get the parsed query in json format

There is only one POST endpoint at https://api.aawadia/dev/sql-parser/v1

Request should contain the sql query that should be parsed

1
2
3
{
"sql": "select * from users;"
}

The response is the json output of the parsed query

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
46
{
"Query": {
"with": null,
"body": {
"Select": {
"distinct": false,
"top": null,
"projection": [
"Wildcard"
],
"into": null,
"from": [
{
"relation": {
"Table": {
"name": [
{
"value": "users",
"quote_style": null
}
],
"alias": null,
"args": null,
"with_hints": []
}
},
"joins": []
}
],
"lateral_views": [],
"selection": null,
"group_by": [],
"cluster_by": [],
"distribute_by": [],
"sort_by": [],
"having": null,
"qualify": null
}
},
"order_by": [],
"limit": null,
"offset": null,
"fetch": null,
"lock": null
}
}

Counters API now live!

Date: 2022-07-01 15:43:23

Counting is so fundamental to everything we build. It comes up so often in some form or other - I decided to deploy a counters API.

Init a bucket

The first thing a user needs to do is generate a bucket or namespace for their counters - This can be done by making a PUT request to https://api.aawadia.dev/counters/v1/ this will return the name of the bucket in the following format

1
2
3
4
5
{
"result": {
"bucket": "01g6y1vzpvw9emrwx5fsvz2c90"
}
}

All your counters will be of the format 01g6y1vzpvw9emrwx5fsvz2c90-<countername> - Counter names can be created on the fly as requests are made

Increment a counter

To increment or decrement a counter a POST request should be sent to https://api.aawadia.dev/counters/v1/<bucket-countername>/<delta> - delta can be negative as well

This will then result of the counter in the following format

1
2
3
4
5
{
"result": {
"count": 1
}
}

Fetch counter

To get a single counter a GET request can be sent to https://api.aawadia.dev/counters/v1?counter=<bucket-counter> which will return the count in the same format as above

1
2
3
4
5
{
"result": {
"count": 1
}
}

The same endpoint is overloaded to get all counters under a namespace by sending the query parameter bucket instead of counter with the bucket i.e. https://api.aawadia.dev/counters/v1?bucket=<bucket>

Delete a counter

A single counter can be deleted by sending a reset request, which is a DELETE request to https://api.aawadia.dev/counters/v1?counter=<bucket-counter>

Morse code API now live!

Date: 2022-06-24 15:43:23

Morse code allows converting the given input to a sequence of dots and dashes.

The request takes in a single string input with key input eg https://api.aawadia.dev/morse-code/v1?input=hello, which will return the encoded version in the following format

1
2
3
4
{
"elapsedUs": 42,
"morse": ".... . .-.. .-.. ---"
}

Decoding is also available by sending the morse code as the input and another parameter type with value decode eg https://api.aawadia.dev/morse-code/v1?input=....%20.%20.-..%20.-..%20---&type=decode Don’t forget to URL encode the spaces or pass it as json via the request body

This will return the original string in the following format

1
2
3
4
{
"elapsedUs": 6,
"output": "HELLO"
}

Geo and misc APIs now live!

Date: 2022-06-23 15:43:23

Namespaces

Two new namespaces were added to the api, misc and geo - misc is a dump of all misc utility type stuff and geo will have anything relating to geo location.

Misc

Misc received two new endpoints. One to generate heroku style names and one to get a random motivational statement, quote, or joke.

To get a random motivational statement, quote, or joke use https://api.aawadia.dev/misc/v1/daily - specify the type using the query parameter ?type=motivation - if not specified quote is assumed by default

1
2
3
4
5
6
7
8
{
"result": {
"motivation": {
"text": "Success is a lousy teacher. It seduces smart people into thinking they can’t lose.",
"from": "Bill Gates"
}
}
}

Haikunator is another useful endpoint - it generates heroku style names. https://api.aawadia.dev/misc/v1/haiku

1
2
3
4
5
{
"result": {
"haiku": "flat-salad-610771"
}
}

Geo

Geo endpoints currently include the ability to work with OpenLocation Codes aka plus codes - 3 endpoints were added

  1. Encode https://api.aawadia.dev/geo/v1/olc-encode?lat=20.3700625&long=2.7821875

Converts a lat and long pair to an OLC

1
2
3
4
5
{
"result": {
"plusCode": "7FG49QCJ+2V"
}
}
  1. Decode https://api.aawadia.dev/geo/v1/olc-decode?code=7FG49QCJ%2B2V - don’t forget to url encode the +

Converts an OLC to Lat and Long data

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"result": {
"codeArea": {
"southLatitude": 43.6425,
"westLongitude": -79.387125,
"northLatitude": 43.642625,
"eastLongitude": -79.387,
"length": 10,
"latitudeHeight": 0.00012500000000414957,
"longitudeWidth": 0.00012499999999704414,
"centerLatitude": 43.6425625,
"centerLongitude": -79.3870625
}
}
}
  1. Meta https://api.aawadia.dev/geo/v1/olc-meta?code=7FG49QCJ%2B2V

Provides some basic meta information about the OLC

1
2
3
4
5
6
7
8
9
{
"result": {
"meta": {
"valid": true,
"full": true,
"short": false
}
}
}

Language detection API now live!

Date: 2022-06-18 18:49:11

The API provides a language detection service i.e. given a piece of text identify what language it is. Currently it supports over 80 languages. The longer the text that is provided the better the prediction. Unfortunately, due to the algorithm used English is poorly supported [ironically]

Server

The server is up now and should be alive at https://api.aawadia.dev/lang-detect/v1/

It takes in a single parameter via query parameters or json request body with key script that should be the text of the language that needs to be detected eg https://api.aawadia.dev/lang-detect/v1?script=чтотыделаешь

The response is in the following format and includes the name of the language and the confidence, which is a float between 0 and 1.

1
2
3
4
5
6
{
"confidence": 1,
"elapsedUs": 290,
"language": "Russian",
"languageCode": 60
}

Chronos API now live!

date: 2022-05-18 18:12:26

One of the most important and challenging aspect of a distributed database is the need to keep track of time. This provides some order to the writes, which can determine the sequence they are applied to the underlying storage. I just finished deploying a Chronos api that provides some sort of centralized clock service to allow for ordering.

NTP time is reasonably accurate but requires sending the request over datagram socket - Chronos provides an easy to use HTTP api that wraps the underlying NTP request

Server

The server is up now and should be alive at https://api.aawadia.dev/chronos/v1/time, which will return the NTP time from Google’s server in the following format

1
2
3
4
5
6
7
8
9
10
11
{
"result": {
"instant": "2022-05-18T22:33:53.820Z",
"seconds": 1652913233,
"milliseconds": 1652913233820,
"leap": 0,
"mode": 4,
"stratum": 1,
"referenceTime": 1652913233820
}
}

Sending a query parameter ?simple=true will return the server time directly in the following format

1
2
3
4
5
6
7
{
"result": {
"instant": "2022-05-18T22:34:24.657971149Z",
"seconds": 1652913264,
"milliseconds": 1652913264657
}
}

Sending a query parameter ?sequence=true will return a monotonically increasing ULID [lexicographically sortable unique ID]

1
2
3
4
5
{
"result": {
"sequence": "01g3cmy3vdxskmkkw7bjsmkzs3"
}
}

SLA

Best effort :)