PATCH call not updating field via API - python

Have a function to update a field in Netbox via API. The same data works on the Django web interface so I know it's not that, just something in my script that I'm doing wrong.
def change_allocated_server_status(api_token="", limit="",jira_access=""):
api_token_here = "Token " + api_token
headers = {'Authorization': api_token_here}
params = {'limit': limit}
sites = "https://my-url.com/api/dcim/devices/?role=server-planned"
session = requests.Session()
site_response = session.get(sites, headers=headers, params=params)
site_results = site_response.json()['results']
allocated_servers = get_devices_by_dc_loca(api_token, limit, jira_access)
url = "https://my-url.com/api/dcim/devices/239"
update = {
"device_role": 41
}
change = requests.patch(url, headers=headers, data=update)
change_results = change.json()
print change_results
The output of print change_results is
{u'status': 2, u'device_role': 40, u'name': u'device-name', u'site': 1, u'comments': u'', u'rack': 4, u'asset_tag': None, u'platform': None, u'primary_ip4': None, u'device_type': 7, u'primary_ip6': None, u'custom_fields': {}, u'position': 5, u'serial': u'', u'face': 0, u'id': 239, u'tenant': 1}
device_role isn't being changed. Doing a print change.status_code returns 200 so I know I'm hitting the API without a authentication problem, just guessing it's something simple I'm missing

Was missing a '/' from the end of my url, stopping the PATCH from being called but throwing no error.

Related

How do I make an API call and authenticate it with a given API key using Python?

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,
...

Using python to get a track from the spotify API by using search Endpoint

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 =)

Questrade API - Placing Order

Noob questions here but I am trying to place an order using Questrade API. This is my python script so far:
import requests
uri = "https://api01.iq.questrade.com/v1/accounts/<id>/orders"
headers = {'Authorization': 'Bearer <my_bearer>'}
r = requests.post(uri, headers=headers, accountNumber=31455565, symbolId=8049, quantity=10, icebergQuantity=1, limitPrice=10, isAllOrNone=True, isAnonymous=False, timeInForce="GoodTillCanceled", primaryRoute="Auto", secondaryRoute="Auto", orderType="Limit", action="Buy")
response = r.json()
print (response)
This is a sample request from Questrade's webpage:
http://www.questrade.com/api/documentation/rest-operations/order-calls/accounts-id-orders
This is the error I'm getting: TypeError: request() got an unexpected keyword argument 'quantity'
Any help will be highly appreciated. Thankss!
All the parameters of your request (accountNumber, symbolId, quantity, ...) are parameters for Questrade API, not for the post method of request. You need to set them in the body of the request, in json format: http://docs.python-requests.org/en/master/user/quickstart/#more-complicated-post-requests
import requests
uri = "https://api01.iq.questrade.com/v1/accounts/<id>/orders"
headers = {'Authorization': 'Bearer <my_bearer>'}
payload = {'accountNumber': 31455565, 'symbolId': 8049, 'quantity': 10, 'icebergQuantity': 1, 'limitPrice': 10, 'isAllOrNone': True, 'isAnonymous': False, 'timeInForce': "GoodTillCanceled", 'primaryRoute': "Auto", 'secondaryRoute': "Auto", 'orderType': "Limit", 'action': "Buy"}
r = requests.post(uri, headers=headers, json=payload)
response = r.json()
print (response)
I created a simple python wrapper to access the questrade API. https://github.com/antoineviscardi/questradeapi
Using it you would get something like this:
import questradeapi as qapi
sess = qapi.Session(<your_bearer>)
sess.post_order(31455565, 8049, 10, 1, 10, None, True, False, "Limit",
"GoodTillCanceled", "Buy", "Auto", "Auto)

Getting error 404 while trying to update a value in Rest API of Openhab using Python request.put

I am trying to update a value in REST API of openhab using requests.put in Python. But I am getting error 404.
My code is copied below
import requests
import json
from pprint import pprint
TemperatureA_FF_Office = 20
headers = {'Content-type': 'application/json'}
payload = {'state' : TemperatureA_FF_Office}
payld = json.dumps(payload)
re = requests.put("http://localhost:8080/rest/items/TemperatureA_FF_Office
/state/put", params= payld, headers = headers)
pprint(vars(re))
The error code I am getting is
{'_content': '',
'_content_consumed': True,
'connection': <requests.adapters.HTTPAdapter object at 7fd3b55ec9d0>,
'cookies': <<class 'requests.cookies.RequestsCookieJar'>[]>,
'elapsed': datetime.timedelta(0, 0, 4019),
'encoding': None,
'history': [],
'raw': <urllib3.response.HTTPResponse object at 0x7fd3b55ecd90>,
'reason': 'Not Found',
'request': <PreparedRequest [PUT]>,
'status_code': 404,
'url': u'http://localhost:8080/rest/items/TemperatureA_FF_Office/state/put?state=21.0'}
Is this the way to use requests.put? Please help.
Try something along these lines:
import requests
req = "http://localhost:8080/rest/items/YOUR_SENSOR_HERE/state"
val = VARIABLE_WITH_YOUR_SENSOR_DATA
try:
r = requests.put(req,data=val)
except requests.ConnectionError as e:
r = "Response Error"
print e
print r
This is a massively simplified version of what I'm using for some of my presence detection and temperature scripts.
The printing of 'r' and 'e' is useful for debug purposes and can be removed once you've got your script working properly.

Reddit API and voting. Not accepting modhash/cookie. .error.USER_REQUIRED

I'm trying to get the voting API working, but I get the error .error.USER_REQUIRED. Can't figure out why, but I assume I must either be sending the modhash or the session cookie the wrong way, as the login goes trough fine
My code looks something like this:
UP = {'user': username, 'passwd': password, 'api_type': 'json',}
client = requests.session()
r = client.post('http://www.reddit.com/api/login', data=UP)
j = json.loads(r.text)
mymodhash = j['json']['data']['modhash']
url = 'http://www.reddit.com/api/vote/.json'
postdata = {'id': thing, 'dir': newdir, 'uh': mymodhash}
vote = client.post(url, data=json.dumps(newdata))
Error:
{"jquery": [[0, 1, "refresh", []], [0, 2, "attr", "find"], [2, 3, "call", [".error.USER_REQUIRED"]], [3, 4, "attr", "show"], [4, 5, "call", []], [5, 6, "attr", "text"], [6, 7, "call", ["please login to do that"]], [7, 8, "attr", "end"], [8, 9, "call", []]]}
To login you should post to ssl.reddit.com so that you are not posting your credentials in plain-text. Also, you should set a User-Agent.
The below is a working example to vote on your /r/redditdev submission.
import requests
# Login
client = requests.session(headers={'User-Agent': 'Requests test'})
data = {'user': 'USERNAME', 'passwd': 'PASSWORD', 'api_type': 'json'}
r = client.post('https://ssl.reddit.com/api/login', data=data)
modhash = r.json['json']['data']['modhash']
# Vote
data = {'id': 't3_11mr32', 'dir': '1', 'uh': modhash, 'api_type': 'json'}
r = client.post('http://www.reddit.com/api/vote', data=data)
print r.status_code # Should be 200
print r.json # Should be {}
Also, unless you are really interested in how reddit's API works under the covers, I suggest you use PRAW.
You can use session object with with statement.
import requests
UP = {'user': username, 'passwd': password, 'api_type': 'json'}
url_prefix = "http://www.reddit.com"
with requests.session() as client:
client.post(url_prefix + '/login', data=UP)
<...something else what you want...>

Categories

Resources