Reputation: 195
Completely new to REST APIs and still learning python, so I apologize for a simple question and being a noob. Any help is appreciated.
I am trying to pull data from a server with with a GET request. The Instructions for doing so are provided on their website here: Ayyeka REST API and I've read through their help documentation as well. It indicates you have to use swagger_client
but I had trouble getting that working. Instead I cobbled together some code using the requests module and I seem to be getting a token correctly using OAuth2.
import os, string, time
from requests.auth import HTTPBasicAuth
from requests.structures import CaseInsensitiveDict
import base64
#credentials
client_id= "[client id goes here]"
client_secret = "[secret goes here]"
secret64 = base64.b64encode(bytes(client_id + ':' + client_secret, 'utf-8')).decode('utf-8')
#time and stream to pull data from
dtime = 1617821133
AyyekaChannel_text = '183534'
token_url = 'https://restapi.ayyeka.com/auth/token'
base_url = 'https://restapi.ayyeka.com '
auth = HTTPBasicAuth(client_id, client_secret)
client = BackendApplicationClient(client_id=client_id)
oauth = OAuth2Session(client=client)
token = oauth.fetch_token(token_url='https://restapi.ayyeka.com/auth/token', auth=auth)
access_token = token['access_token']
headers = {'Authorization': 'Bearer ' + access_token}
response = requests.get(url=base_url,headers=headers)
token
returns:
{'access_token': '[token string appears here]', 'token_type': 'JWT', 'expires_in': 3600,'expires_at': 1617909733.2390773}
Now I'm stuck and am not sure how to pass this through a GET to get an Authentication token, and not sure how to use the REST commands to pull data. Am I on the right track at all? Completely off the mark? response
just returns a bunch of errors, but I know it's not right anyways but I can't figure out the next step since their documentation uses swagger_client
. I'm not sure if I should go back to trying to get swagger_client
working or if this should work?
Upvotes: 0
Views: 227
Reputation: 456
It's hard to give a good example since I don't have access to their help documentation. That said, it looks like you're getting a JWT token and you're passing a header with said token. I would be curious to know exactly what error you're getting in the response. You can check that with response.status_code and response.text.
You have a space in your base_url variable base_url = 'https://restapi.ayyeka.com '
instead of base_url = 'https://restapi.ayyeka.com'
. That could be part of your problem. You are also not appending any actual API endpoint. Also, their documentation shows in their curl example that there should be a version appended to that URL (see my base_url
below).
As barny said, you probably want to be using requests.Session() here. You asked how to do that in a comment and here's how:
dtime = 1617821133
AyyekaChannel_text = "183534"
base_url = "https://restapi.ayyeka.com/v2.0"
session = requests.Session()
session.headers.update({"Authorization": f"Bearer {access_token}"})
params = {
"sampleID": AyyekaChannel_text,
"backfillHours": dtime,
}
session.get(url=f"{base_url}/sample/batch", params=params)
All that being said, the documentation says regarding backfillHours
:
Specifies to send samples starting this many hours ago. For example, if the backfillHours value is 24, this is a request to provide all samples of the past 24 hours
I don't know what your intended use of dtime
here is, but obviously 1617821133
is like 180,000+ years in the past, but I used it here as an example of how you would pass that value as a query parameter in the request assuming it were a sane value.
You would probably also have use for making this whole thing object-oriented. Here's a really short example for illustration purposes:
class AyyekaClient:
"""A client implementing the Ayyeka API."""
def __init__(self, client_id: str, client_secret: str):
self.base_url = "https://restapi.ayyeka.com/v2.0"
self.client_id = client_id
self.client_secret = client_secret
self.auth = HTTPBasicAuth(client_id, client_secret)
self.client = BackendApplicationClient(client_id=self.client_id)
self.oauth = OAuth2Session(client=self.client)
self.session = requests.Session()
self.session.hooks["response"] = [self.raise_for_status]
self.refresh_access_token()
def raise_for_status(response, *args, **kwargs):
"""Requests event hook to call raise_for_status on every request."""
response.raise_for_status()
def refresh_access_token(self):
"""Get a fresh access token."""
token = self.oauth.fetch_token(token_url="https://restapi.ayyeka.com/auth/token", auth=self.auth)["access_token"]
self.session.headers.update({"Authorization": f"Bearer {token}"})
def get_sample_scalar_batch(self, sample_id: str, backfill_hours: int) -> requests.Response:
"""Get a Batch of New SamplesScalar."""
params = {"sampleID": sample_id, "backfillHours": backfill_hours}
return self.session.get(url=f"{self.base_url}/sample/batch", params=params)
Then you would implement that class like:
ayyeka = AyyekaClient(client_id="123456", client_secret="78910112")
response = ayyeka.get_sample_scalar_batch(sample_id, backfill_hours)
print(response.text)
print(response.json())
Those JWT tokens only have a 1 hour lifetime, so you'd occasionally need to call ayyeka.refresh_access_token()
or do some sort of error handling where if the request fails due to a 401/403 error you refresh the token and try the request again. That method will automatically get a new token and update the session's Authorization header to utilize the token.
This was just meant to be an illustrative example of how you might go about using a class here. I haven't put a tremendous amount of thought into it. You would implement the rest of the API endpoints as methods on this class, then you'd implement the client in a separate script/module.
Upvotes: 1