I am trying to retrieve data from the first available date to present date from an API. I've tried using min and max in parameter.
def getcomplete(cid, pid, tag, type):
api_endpoint = ''
headers = {'token': get_token()['access_token'], 'Content-Type': 'application/json'}
params = {'cid': str(cid),
'from-date': datetime.datetime.min,
'to-date': datetime.datetime.max,
'tag': str(tag),
'type': str(type),
'pid': str(pid)
}
r = requests.post(url=api_endpoint, headers=headers, params=params)
return r.json()
getcomplete(10,12,'x','y')
This returns {'status': 'success', 'message': 'success', 'data': []}.
Is there anything wrong with the written function.
Thanks
Pythons min() and max() have an optional default parameter. This will prevent them from throwing errors
min("", default="")
Related
I'am trying to make an API request where I add some optional values but if I don't add them I don't want them to be in the request.
In this case, I would like the parameters to be 'startblock' & 'endblock'
def get_transactions_by_address_(self, address, action='txlist'):
"""
:param address:
:param action: [txlist, txlistinternal]
:return:
"""
token = self.etherscan_api_key
return requests.get('https://api.etherscan.io/api'
'?module=account'
f'&action={action}'
f'&address={address}'
# '&startblock=0'
# '&endblock=92702578'
'&page=1'
'&offset=1000'
'&sort=desc'
f'&apikey={token}'
)
I was thinking on adding some conditionals like
request_url = 'https://api.etherscan.io/api...'
if startblock:
request_url = request_url + f'&startblock={startblock}'
if endblock:
request_url = request_url + f'&endblock={endblock}'
But I don't know if it is the most pythonic way to do it and I would like to get other options on how to do it
Use the payload option instead of constructing the URL yourself. For example, create a dict containing all the required options, then add additional parameters to the dict as necessary. requests.get will build the required URL from the base URL and the values found in your dict.
options = {
'module': 'account',
'action': action,
'address': address,
'apikey': token,
'sort': sort,
'page': page,
'offset': offset
}
if startblock:
options['startblock'] = startblock
if endblock:
options['endblock'] = endblock
return requests.get('https://api.etherscan.io/api', params=options)
The correct way to implement is:
def get_transactions_by_address_(self, address,
action='txlist',
sort='desc',
page=1,
offset=1000,
startblock=None,
endblock=None):
token = self.etherscan_api_key
options = {
'module': 'account',
'action': action,
'address': address,
'apikey': token,
'sort': sort,
'page': page,
'offset': offset
}
if startblock:
options['startblock'] = startblock
if endblock:
options['endblock'] = endblock
return requests.get('https://api.etherscan.io/api',
params=options
)
This is my code to extract player data from an endpoint containing basketball data for a Data Science project.NOTE: I changed the name of the actual API key I was given since it's subscription. And I change the username/password because for privacy purposes. Using the correct credentials, I wouldn't receive a syntax error but the status code always returns 401. Since it wasn't accepting the API key, I added my account username, password, and the HTTP authentication header as well, but the status code still returns 401.
In case this is relevant, this is the website's recommendation in the developer portal: **The API key can be passed either as a query parameter or using the following HTTP request header.
Please let me know what changes I can make to my code. Any help is appreciated.
Ocp-Apim-Subscription-Key: {key}**
PS: My code got fragmented while posting this, but it is all in one function.
def getData():
user_name = "name#gmail.com"
api_endpoint = "https://api.sportsdata.io/v3/nba/stats/json/PlayerGameStatsByDate/2020-FEB7"
api_key = "a45;lkf"
password = "ksaljd"
header = "Ocp-Apim-Subscription-Key"
PARAMS = {'user': user_name, 'pass': password, 'header': header, 'key': api_key}
response = requests.get(url = api_endpoint, data = PARAMS)
print(response.status_code)
file = open("Data.csv", "w")
file.write(response.text)
file.close()
def _get_auth_headers() -> dict:
return {
'Content-Type': 'application/json',
'Ocp-Apim-Subscription-Key': "`Insert key here`"
}
api_endpoint = "https://api.sportsdata.io/v3/nba/stats/json/PlayerGameStatsByDate/2020-FEB7"
PARAMS = {
# Your params here
}
response = requests.get(
api_endpoint,
headers=_get_auth_headers(),
params=PARAMS
)
Instead of just a string, you need to pass dict in the headers parameter and auth param exist so you can use it as follow:
def getData():
[...]
header = {
"Ocp-Apim-Subscription-Key": api_key
}
[...]
response = requests.get(url = api_endpoint, data = PARAMS, headers=header, auth = (user_name, password))
According to the API documentation you don't need to provide email and password. You're only need to add your API Key to header:
import requests
r = requests.get(url='https://api.sportsdata.io/v3/nba/stats/json/PlayerGameStatsByDate/2020-FEB7', headers={'Ocp-Apim-Subscription-Key': 'API_KEY'})
print(r.json())
Output:
[{
'StatID': 768904,
'TeamID': 25,
'PlayerID': 20000788,
'SeasonType': 1,
'Season': 2020,
'Name': 'Tim Hardaway Jr.',
'Team': 'DAL',
'Position': 'SF',
'Started': 1,
'FanDuelSalary': 7183,
'DraftKingsSalary': 7623,
'FantasyDataSalary': 7623,
...
I am consuming the Yelp API and using this detail view to display details of individual restaurants such as the name, rating and price of a restaurant. The detail dictionary is solid for the most part and lets me collect variables to use as context in template. However some restaurants do not provide their 'price' to the API, therefore when accessing this view I get a KeyError because there is no price in some cases. How can I create this dictionary with a None value for price to avoid this error? Or is exception handling with try & except the best solution?
def detail(request, api_id):
API_KEY = 'unique_key'
url = 'https://api.yelp.com/v3/businesses/'+ api_id
headers = {'Authorization': 'Bearer {}'.format(API_KEY)}
req = requests.get(url, headers=headers)
parsed = json.loads(req.text)
detail = {
'id': parsed['id'],
'name': parsed['name'],
'rating':parsed['rating'],
'price': parsed['price'],
}
context = {'detail': detail}
return render(request, 'API/detail.html', context)
You can use <dict>.get('key', default_value):
detail = {
'id': parsed['id'],
'name': parsed['name'],
'rating':parsed['rating'],
'price': parsed.get('price', None), # <-- here
}
W3School has a nice example on how to use .get() method.
you can try:
detail = {
'id': parsed['id'],
'name': parsed['name'],
'rating':parsed['rating'],
'price': parsed['price'] if parsed['price'] else None,
}
So I'm trying to get a track from the spotify API by searching for it by using the search endpoint of the API (See documentation). First, I authorize myself so I can send GET requests. This happens without issues, I added the code for reproducibility.
import requests
CLIENT_ID = "your_id_here"
CLIENT_SECRET = "your_secret_here"
AUTH_URL = "https://accounts.spotify.com/api/token"
auth_response = requests.post(AUTH_URL, {
'grant_type': 'client_credentials',
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET,
})
#Convert response to JSON
auth_response_data = auth_response.json()
#Save the access token
access_token = auth_response_data['access_token']
#Need to pass access token into header to send properly formed GET request to API server
headers = {
'Authorization': 'Bearer {token}'.format(token=access_token)
}
Then, I want to use the search endpoint of the API to find a track by using the track name + artist (I need the track ID later on). When I use the example provided in the documentation, everything works fine and an artist object is returned by using the following query:
BASE_URL = 'https://api.spotify.com/v1/'
r = requests.get(BASE_URL + 'search?q=tania%20bowra&type=artist', headers=headers)
r = r.json()
This is the response, which looks exactly like the one in documentation:
{'artists': {'href': 'https://api.spotify.com/v1/search?query=tania+bowra&type=artist&offset=0&limit=20',
'items': [{'external_urls': {'spotify': 'https://open.spotify.com/artist/08td7MxkoHQkXnWAYD8d6Q'},
'followers': {'href': None, 'total': 235},
'genres': [],
'href': 'https://api.spotify.com/v1/artists/08td7MxkoHQkXnWAYD8d6Q',
'id': '08td7MxkoHQkXnWAYD8d6Q',
'images': [{'height': 640,
'url': 'https://i.scdn.co/image/ab67616d0000b2731ae2bdc1378da1b440e1f610',
'width': 640},
{'height': 300,
'url': 'https://i.scdn.co/image/ab67616d00001e021ae2bdc1378da1b440e1f610',
'width': 300},
{'height': 64,
'url': 'https://i.scdn.co/image/ab67616d000048511ae2bdc1378da1b440e1f610',
'width': 64}],
'name': 'Tania Bowra',
'popularity': 1,
'type': 'artist',
'uri': 'spotify:artist:08td7MxkoHQkXnWAYD8d6Q'}],
'limit': 20,
'next': None,
'offset': 0,
'previous': None,
'total': 1}}
Applying the same logic, I tried to get a track object from the api by using an artist and a track name, like so:
BASE_URL = 'https://api.spotify.com/v1/'
r = requests.get(BASE_URL + 'search?q=artist:queen%20track:bohemian%20rapsody&type=track', headers=headers)
r = r.json()
Even though I do get a valid response (statuscode==200), it seems to be empty:
{'tracks': {'href': 'https://api.spotify.com/v1/search?query=artist%3Aqueen+track%3Abohemian+rapsody&type=track&offset=0&limit=20',
'items': [],
'limit': 20,
'next': None,
'offset': 0,
'previous': None,
'total': 0}}
My question is: why is this happening?
You are now searching for the query: artist:queen%20track:bohemian%20rapsody while this should just be queen%20bohemian%20rapsody instead. the type afterwards shows what items you want to return. You dont have to determine the artist and track name seperately in the query. Interpret the query just like typing something into the spotify search bar.
Problem solved. It was rhapsody instead of rapsody... Sucks be a non-native english speaker sometimes =)
I have the following the following code
response = requests.get(url, headers=headers)
response_dict = response.json()
print(response_dict)
user_name = response_dict['data']['username']
password = response_dict['data']['password']
My print returns:
{'request_id': 'hidden', 'lease_id': 'hidden', 'renewable': True, 'lease_duration': 3600, 'data': {'password': 'hidden', 'username': 'hidden'}, 'wrap_info': None, 'warnings': None, 'auth': None}
I get a key error
'data': KeyError
What seems to be the mistake here?
The issue was with my VPC once the code was pushed to a lambda, I did not have permission to move forward with requests sometimes due to race condition.