A rest db api designed to be integrated with apache superset
Project description
REST-DB-API
This is a plugin to be used with apache-superset, for importing data via REST APIs.
It builds on top of shillelagh's generic json adapter.
To get started, just do:
pip install rest-db-api
Motivation
- Generic json adapter did not support request bodies and headers.
- Independence to specify http/https
restdialect enables this adapter to be used with apache superset.- The dialect enables us to set a base URL, and query multiple endpoints with the same 'connection'.
Examples
GET requests
Querying weather api
Lets assume I am querying for 3 days weather forecast for Bangalore. The response gives the results by hour.
https://api.weatherapi.com/v1/forecast.json?key={{your_key}}&q=Bangalore&days=3&aqi=no&alerts=no
You can get a free key by creating an account there.
You can refer this file to check the response structure.
We can query this with rest-db-api:
from sqlalchemy import create_engine
from rest_db_api.utils import get_virtual_table
engine = create_engine("rest://api.weatherapi.com?ishttps=1")
endpoint = '/v1/forecast.json'
params = {
'key': 'your_key',
'q': 'Bangalore',
'days': 5
}
jsonpath = "$.forecast.forecastday[*]"
virtual_table = get_virtual_table(endpoint=endpoint,
params=params,
jsonpath=jsonpath)
connection = engine.connect()
for i in connection.execute(f'SELECT * FROM "{virtual_table}"'):
print(i)
The response should return an array of objects/primitives. If not, we need to specify where in the response the array is (using jsonpath). In this case that is at $.forecast.forecastday[*]
As Shillelagh's Adapter class uses in memory storage - sqllite , we can query the data using sqllite syntax.
query = f"""
SELECT
date,
json_extract(day, "$.maxtemp_c") as max_temp_celsius,
json_extract(hour, "$[6].temp_c") as six_am_celsius,
json_extract(hour, "$[6].will_it_rain") as will_it_rain
FROM
"{virtual_table}"
"""
for i in connection.execute(query):
print(i)
POST request with headers and request body
Consider this sample request
curl --location -g --request POST 'https://some.api.com/some/api/path?a=60&c=someQuery&b=-50#$[*]' \
--header 'Content-Type: application/json' \
--header 'IAM_ID: satvik' \
--header 'ENVIRONMENT: staging:1.5.3' \
--header 'NAME: MY-REST-SERVICE' \
--data-raw '{
"name": "satvik",
"interests": [
{
"name": "badminton",
"category": "sports",
"stats": {
"racket": "intermediate",
"shuttle": "yonex mavis 500"
}
},
{
"name": "programming",
"category": "computers",
"stats": {
"laptop": "yw",
"mouse": "5D ergonomic",
"keyboard": "broken"
}
}
]
}'
To query this with db-api, follow the snippet:
from sqlalchemy import create_engine
from rest_db_api.utils import get_virtual_table
engine = create_engine("rest://some.api.com?ishttps=1")
endpoint = '/some/api/path'
params = {
"a": 60,
"b": -50,
"c": "someQuery"
}
headers = {
'Content-Type': 'application/json',
'IAM_ID': 'satvik',
'ENVIRONMENT': 'staging:1.5.3',
'NAME': 'MY-REST-SERVICE',
}
body = {
"name": "satvik",
"interests": [
{
"name": "badminton",
"category": "sports",
"stats": { "racket": "intermediate", "shuttle": "yonex mavis 500" }
},
{
"name": "programming",
"category": "computers",
"stats": {
"laptop": "mac book pro",
"mouse": "5D ergonomic",
"keyboard": "broken"
}
}
]
}
jsonpath = "#$[*]" # set this according to your response
virtual_table = get_virtual_table(endpoint=endpoint,
params=params,
headers=headers,
body=body,
jsonpath=jsonpath)
for i in connection.execute(f'SELECT * FROM "{virtual_table}"'):
print(i)
Usage with apache-superset
-
Go to Connect database and add database
-
Select Shillelagh
-
add the connection string with
rest://prefix eg:rest://api.weatherapi.com?ishttps=1 -
Gice your connection a name: eg
rest-weather-api -
Click test connection and then add
-
Go to SQL lab and select
rest-weather-apifrom database. -
You can leave schema empty and query directly!!
Query is:
SELECT date,
json_extract(day, "$.maxtemp_c") as max_temp_celsius,
json_extract(hour, "$[6].temp_c") as six_am_celsius,
json_extract(hour, "$[6].will_it_rain") as will_it_rain
FROM "/v1/forecast.json?key={your_key}&q=Bangalore&days=5#$.forecast.forecastday[*]";
Tables and schema is empty, because there's no concept for tables in REST APIs.
It returns a default message. That message is configured in rest_api_dialect.py
Getting the virtual table
In superset's SQL lab, we're directly using
/v1/forecast.json?key={your_key}&q=Bangalore&days=5#$.forecast.forecastday[*]
To get the similar virtual table address for your endpoint (it may have headers or even body), use the utility rest_db_api.utils.get_virtual_table and pass in your configs.
- POST requests (request body)
- headers
- adding write support to adapter (for PUT/DELETE requests)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file rest-db-api-0.0.3.tar.gz.
File metadata
- Download URL: rest-db-api-0.0.3.tar.gz
- Upload date:
- Size: 12.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.8.17
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e29c435491ad186362c81fe6021f57fbc1399d56ab04ae6fd4b45ea734523242
|
|
| MD5 |
16f3d78e6d0ce28d4dd3cdb6ae791d74
|
|
| BLAKE2b-256 |
98458ebb54c7a0491766702bc1e06a43b827ddc87cbea0dd737dddf313481d9e
|
File details
Details for the file rest_db_api-0.0.3-py3-none-any.whl.
File metadata
- Download URL: rest_db_api-0.0.3-py3-none-any.whl
- Upload date:
- Size: 9.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.8.17
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
73e84807b5a9d3fc2bbd386af3b83939c75efab36004df75105939f2f1bc9d6d
|
|
| MD5 |
5795d1e6e8b149dc47c7319f77a8d4ef
|
|
| BLAKE2b-256 |
707dff3da16cefbf5c09732ca84f65596493a31bff3566fdbeb27a8c52d75537
|