11import json
22import logging
33import os
4- from time import sleep
54
65import requests
76
87from ravenpackapi import Dataset
98from ravenpackapi .exceptions import APIException
10- from ravenpackapi .models .dataset import DatasetList
11- from ravenpackapi .models .job import Job
9+ from ravenpackapi .models .dataset_list import DatasetList
10+ from ravenpackapi .models .results import Results
1211from ravenpackapi .util import to_curl
12+ from ravenpackapi .utils .constants import JSON_AVAILABLE_FIELDS
1313
1414_VALID_METHODS = ('get' , 'post' , 'put' , 'delete' )
1515
1616logger = logging .getLogger ("ravenpack.core" )
1717
1818
1919class RPApi (object ):
20- _BASE_URL = os .environ .get ('RP_API_ENDPOINT' , 'https://api.ravenpack.com/1.0' )
21- _FILE_AVAILABILIY_SECONDS_DELAY = 5.0
22- _CHUNK_SIZE = 1024 * 32
20+ _BASE_URL = os .environ .get ('RP_API_ENDPOINT' ,
21+ 'https://api.ravenpack.com/1.0' )
2322
24- def __init__ (self , api_key ):
23+ def __init__ (self , api_key = None ):
2524 api_key = api_key or os .environ .get ('RP_API_KEY' )
2625 if api_key is None :
2726 raise ValueError (
2827 "Please initialize with an api_key "
29- "or set your environment RP_API_KEY with a permanent token "
28+ "or set your environment RP_API_KEY with your API KEY. "
3029 )
3130 self .api_key = api_key
3231
33- def request (self , endpoint , data = None , method = 'get' ):
32+ def request (self , endpoint , data = None , params = None , method = 'get' ):
3433 assert method in _VALID_METHODS , 'Method {used} not accepted. Please use {valid_methods}'
3534 logger .debug ("Request to %s" % endpoint )
3635 requests_call = getattr (requests , method )
@@ -40,79 +39,70 @@ def request(self, endpoint, data=None, method='get'):
4039 url = self ._BASE_URL + endpoint ,
4140 headers = dict (API_KEY = self .api_key ),
4241 data = json .dumps (data ) if data else None ,
42+ params = params ,
4343 )
4444 if response .status_code != 200 :
4545 logger .error ("Error calling the API, we tried: %s" % to_curl (response .request ))
46- raise APIException ('Got an error {status}: {error_message}' .format (
47- status = response .status_code , error_message = response .text
48- ), response = response )
46+ raise APIException (
47+ 'Got an error {status}: body was \' {error_message}\' ' .format (
48+ status = response .status_code , error_message = response .text
49+ ), response = response )
4950 return response
5051
51- def list_datasets (self , tags = None , scope = None ):
52+ def list_datasets (self , scope = None , tags = None ):
5253 """ Return a DataSetList of datasets in the scope """
53- response = self .request ('/datasets' , data = dict (
54- tags = tags or [] ,
54+ response = self .request ('/datasets' , params = dict (
55+ tags = tags or None ,
5556 scope = scope or 'private' ,
5657 ))
57- return DatasetList (map (Dataset .from_dict , response .json ()['datasets' ]))
58+ return DatasetList (
59+ map (lambda item : Dataset .from_dict (item , api = self ),
60+ response .json ()['datasets' ])
61+ )
5862
5963 def create_dataset (self , dataset ):
6064 response = self .request (endpoint = "/datasets" ,
6165 data = dataset .as_dict (),
6266 method = 'post' )
6367 dataset_id = response .json ()['dataset_uuid' ]
6468 logger .info ("Created dataset %s" % dataset_id )
65- return dataset_id
6669
67- def download_dataset ( self , dataset_id , start_date , end_date ,
68- output_format = 'csv' , compressed = False , notify = False ):
69- response = self . request (
70- endpoint = "/datafile/%s" % dataset_id ,
71- data = {
72- "start_date" : start_date ,
73- "end_date" : end_date ,
74- "format" : output_format ,
75- "compressed" : compressed ,
76- "notify" : notify ,
77- } ,
78- method = 'post' ,
70+ # we return the Dataset object just created
71+ dataset . api = self
72+ new_dataset_data = dataset . as_dict ()
73+ new_dataset_data [ 'uuid' ] = dataset_id
74+ new_dataset = Dataset ( api = self ,
75+ ** new_dataset_data )
76+ return new_dataset
77+
78+ def get_dataset ( self , dataset_id ):
79+ return Dataset (
80+ api = self ,
81+ uuid = dataset_id ,
7982 )
80- job = Job (response .json ()['token' ]) # an undefined job, has just the token
81- return job
8283
83- def get_job_status (self , job ):
84- token = job .token
84+ def json (self ,
85+ start_date ,
86+ end_date ,
87+ fields ,
88+ filters = None ,
89+ time_zone = None ,
90+ frequency = 'granular' ,
91+ having = None ,
92+ product = 'rpa' ,
93+ product_version = '1.0' ,
94+ ):
95+ # let's build the body, with all the defined fields
96+ body = {}
97+ for k in JSON_AVAILABLE_FIELDS :
98+ if locals ().get (k ) is not None :
99+ body [k ] = locals ().get (k )
100+
85101 response = self .request (
86- endpoint = "/jobs/%s" % token ,
87- data = {
88- "token" : token ,
89- },
90- method = 'get' ,
102+ endpoint = "/json" ,
103+ method = 'post' ,
104+ data = body ,
91105 )
92- return Job (token , ** response .json ())
93-
94- def wait_job_to_be_ready (self , job ):
95- logger .info ("Waiting for the job to be ready..." )
96- while True :
97- try :
98- job = self .get_job_status (job )
99- except APIException : # keep waiting if API raises exceptions
100- sleep (self ._FILE_AVAILABILIY_SECONDS_DELAY )
101- continue
102- if not job .is_processing :
103- return job
104- sleep (self ._FILE_AVAILABILIY_SECONDS_DELAY )
105-
106- def save_job_to_file (self , job , filename ):
107- with open (filename , 'wb' ) as output :
108- job = self .wait_job_to_be_ready (job )
109- logger .info (u"Writing to %s" % filename )
110-
111- r = requests .get (job .url ,
112- headers = dict (API_KEY = self .api_key ),
113- stream = True ,
114- )
115-
116- for chunk in r .iter_content (chunk_size = self ._CHUNK_SIZE ):
117- if chunk :
118- output .write (chunk )
106+ data = response .json ()
107+ return Results (data ['records' ],
108+ name = 'Ad-hoc JSON query' )
0 commit comments