Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
MasamichiIdeue committed Jun 29, 2017
0 parents commit a1d4ba0
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 0 deletions.
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Redquery

Python [Redash](https://redash.io/) API Client

## Installation

```sh
$ pip install git+https://github.com/MasamichiIdeue/redquery.git
```


## Usage

```python
from redquery import Client

c = Client('https://redash.example.host', api_key, data_sourece_id)
c.query('query').rows
```
73 changes: 73 additions & 0 deletions redquery/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
from urlparse import urljoin
import json
import time

import requests


class QueryResult(object):
def __init__(self, rows, query):
self.query = query
self.rows = rows

@classmethod
def create(cls, res):
rows = res['query_result']['data']['rows']
query = res['query_result']['query']
return QueryResult(rows, query)


class Client(object):
def __init__(self, host, api_key, data_source_id):
self.api_base = urljoin(host, 'api')
self.api_key = api_key
self.data_source_id = data_source_id

def _api_get(self, resource):
return requests.get(self.api_base + '/' + resource,
headers={'Authorization': 'Key %s' % self.api_key})

def _api_post(self, resource, data):
return requests.post(self.api_base + '/' + resource,
headers={'Authorization': 'Key %s' % self.api_key},
data=json.dumps(data))

def data_sources(self):
return self._api_get('data_sources')

def query(self, query, retry_num=30, interval_sec=1):
res_j = self._post_query(query).json()
retried = 0
while not self._query_completed(res_j):
time.sleep(interval_sec)
res_j = self._post_query(query).json()
retried += 1
if retried > retry_num:
raise Exception('Max retry num reached.')
return QueryResult.create(res_j)

def _post_query(self, query):
data = {
'query': query,
'data_source_id': self.data_source_id
}
return self._api_post('query_results', data)

def _has_result(self, res_json):
return ('query_result' in res_json) and ('retrieved_at' in res_json['query_result'])

def _query_completed(self, res_json):
if self._has_result(res_json):
return True
uncompleted_job = self.job(res_json['job']['id'])
if self._job_has_error(uncompleted_job):
raise Exception(uncompleted_job['job']['error'])
return False

def _job_has_error(self, res_json):
if res_json['job']['error']:
return True
return False

def job(self, jid):
return self._api_get('jobs/%s' % jid).json()
5 changes: 5 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
certifi==2017.4.17
chardet==3.0.4
idna==2.5
requests==2.18.1
urllib3==1.21.1
12 changes: 12 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from setuptools import setup, find_packages

setup(
name='redquery',
version='0.0.1',
description='Redash API Client',
author='Masamichi Ideue',
author_email='[email protected]',
url='https://github.com/MasamichiIdeue/redquery',
license='MIT',
packages=find_packages()
)

0 comments on commit a1d4ba0

Please sign in to comment.