Spotify API Post call – Response 415? - python

Using Python, I'm trying to do a POST call to the Spotify API by following the instructions under the paragraph Client Credentials Flow at the link https://developer.spotify.com/web-api/authorization-guide/#client_credentials_flow and this is the code I have come up with.
However, I get Response [415] when I run it. Can anyone tell me what is wrong?
import pprint
import requests
import urllib2
import json
import base64
client_id='b040c4e03217489aa647c055265d0ac'
client_secret='2c2928bb7d3e43278424002d2e8bda46b'
authorization_param='Basic ' + base64.standard_b64encode(client_id + ':' + client_secret)
grant_type='client_credentials'
#Request based on Client Credentials Flow from https://developer.spotify.com/web-api/authorization-guide/
#Header must be a base 64 encoded string that contains the client ID and client secret key.
#The field must have the format: Authorization: Basic <base64 encoded client_id:client_secret>
header_params={'Authorization' : authorization_param}
#Request body parameter: grant_type Value: Required. Set it to client_credentials
body_params = {'grant_type' : grant_type}
url='https://accounts.spotify.com/api/token'
response=requests.post(url, header_params, body_params) # POST request takes both headers and body parameters
print response

The type of authentication that Spotify is requesting is just basic HTTP authentication. This is a standardised form of authentication which you can read more about here. The requests library supports basic authentication without requiring you to create the headers yourself. See the python requests documentation for information.
The code below uses the request library authentication to connect to the Spotify API.
import requests
client_id = # Enter your client id here
client_secret = # Enter your client secret here
grant_type = 'client_credentials'
#Request based on Client Credentials Flow from https://developer.spotify.com/web-api/authorization-guide/
#Request body parameter: grant_type Value: Required. Set it to client_credentials
body_params = {'grant_type' : grant_type}
url='https://accounts.spotify.com/api/token'
response=requests.post(url, data=body_params, auth = (client_id, client_secret))
print response
I created a test account with Spotify and created a test client id and client secret which worked find for this. I got a response 200 back using python 2.7.6 and requests 2.2.1.

Related

How do I set up a Kerberos Token with client ID and secret for Remedy API in Python?

I am using an Remedy API that needs to be authenticated using a client ID and client secret key. Using basic HTTP authentication (using the request library), I am able to authenticate and get certain information from the API (ticket information). The issue is, with certain accounts we use to generate the client ID and client secret key, I HAVE to use a Kerberos token as well to get all of ticket information.
How do I use Kerberos authentication along with a client ID and client secret key to authenticate using Python?
Here is my syntax for basic authentication:
# example client ID and client secret keys
client_id = '39448jFjkjfiJIRTKK1'
client_secret = '2niwiFuYNh9nfkdf'
token_url = "https://remedy.test.com:8111/token"
payload = {'grant_type': 'client_credentials', 'validity_period': 3600}
headers = {"Content-Type" : "application/x-www-form-urlencoded"}
# Create HTTP request
access_token_response = requests.post(token_url, auth=HTTPBasicAuth(client_id, client_secret), data=payload, headers=headers)
# Get access token
token = access_token_response.json()['access_token']```
The above syntax gets me some of the information I need but not all. Here is what I have tried to get a Kerberos token:
# example client ID and client secret keys
client_id = '39448jFjkjfiJIRTKK1'
client_secret = '2niwiFuYNh9nfkdf'
token_url = "https://remedy.test.com:8111/token"
bt64 = HTTPKerberosAuth()
payload = {'grant_type': 'client_credentials', 'validity_period': 3600}
headers = {"Content-Type" : "application/x-www-form-urlencoded", "Authorization": "Negotiate " + bt64}
# Create HTTP request
access_token_response = requests.post(token_url, auth=HTTPKerberosAuth
(client_id, client_secret), data=payload, headers=headers)```
The above syntax with Kerberos authentication does not seem to work. It just says 'invalid client credentials. I usually use a Remedy Module in Powershell to do this and everything works perfectly with the client ID and client secret keys I have, so I know those are correct.
Any idea on what I am doing wrong?

How can I test AWS Cognito protected APIs in Python?

I'm trying to test out some AWS APIs that are protected by Cognito. I found the first part on how to get the Json token but I can't figure out how to use the token correctly so I can authenticate on the API.
Here's my code :
import boto3 as boto3;
import requests
username='test#gmail.com'
password='test1234567'
client = boto3.client('cognito-idp')
response = client.initiate_auth(
AuthFlow='USER_PASSWORD_AUTH',
AuthParameters={
"USERNAME": username,
"PASSWORD": password,
},
ClientId='12121212121212',
)
token = response['AuthenticationResult']['AccessToken']
#print("Log in success")
#print("Access token:", response['AuthenticationResult']['AccessToken'])
#print("ID token:", response['AuthenticationResult']['IdToken'])
url = 'https://XXXXXXXX.execute-api.eu-west-1.amazonaws.com/Prod/incidents'
#print('url:', url)
#response = requests.get(url, headers={'authorization': token })
#print('GET:', response.status_code)
head = {'Authorization': token}
response = requests.get(url, headers=head)
print(response.content)
I'm getting the following error message :
b'{"message":"Authorization header requires \'Credential\' parameter. Authorization header requires \'Signature\' parameter. Authorization header requires \'SignedHeaders\' parameter. Authorization header requires existence of either a \'X-Amz-Date\' or a \'Date\' header. Authorization=
Ok so I found the problem and it's working fine now, 2 things were wrong :
The endpoint was wrong - AWS doesn't send a correct error message (!)
The request has to be sent with response['AuthenticationResult']['IdToken']
Please make sure you have selected Cognito or IAM in your API Gateway. From the error message it seems you have selected IAM for protecting the API.
Check the Authorization header's name which you configured for your Cognito Authorizer. You need to use same header name while passing the Cognito token.
If you have configured OAuth scopes in API Gateway side, then you must use access token. And no scope is configured then you can use ID token for authorization.
That said, you can try from Postman application for testing purpose.

Scrape Alertmanager API

I have an Openshift 3.11 cluster with the default installation of Prometheus and Alertmanager.
I want to write a python script to scrape the Alertmanager API endpoint so that I can parse the data and pass that on to s third party monitoring tool for our ops team.
My problem is that to get to the API I need to authenticate against oauth. How can I do this within python?
I don't know if this is any different for alert manager compared with the Reddit API, but when I set up a bot for that, I had to first register it on their OAuth page, then I needed to use the codes that it gave me there, to request an access token with the rest of my user data (Login and password as well as what the application was called) Then I could use that authentication to contact the API endpoint.
Here is the function I made to request the access token from Reddit:
def AuthRequest():
import requests
import requests.auth
import json
client_auth = requests.auth.HTTPBasicAuth('Application ID code', 'OAuth secret code')
post_data = {"grant_type": "password", "username": "Your_Username", "password": "Your_Password"}
headers = {"User-Agent": "Name_Of_Application"}
response = requests.post("https://www.reddit.com/api/v1/access_token", auth=client_auth, data=post_data, headers=headers)
return response.json()
And here is the code that contacts the endpoint and takes the data from it:
import requests
import requests.auth
import json
currentComments = []
headers = {"Authorization": auth['token_type'] + " " + auth['access_token'], "User-Agent": "Your_Application_Name"}
mentions = requests.get("https://oauth.reddit.com/message/unread.json", headers=headers).json()
Note here that 'auth' is simply the 'response' from the authentication token. I hope that helps, I don't really know how this differs with alertmanager as I've never really had to use it.
I found the fix for me.
I needed to create a service account
oc create serviceaccount <serviceaccount name> -n <your-namespace>
Then create a cluster role binding for it
oc create clusterrolebinding <name for your role> \
--clusterrole=cluster-monitoring-view \
--serviceaccount=<your-namespace>:<serviceaccount name>
Get a token from the SA and then use that in the curl
oc sa get-token <serviceaccount name> -n <your-namespace>

Firebase DB HTTP API Auth: When and how to refresh JWT token?

I'm trying to make a Python webapp write to Firebase DB using HTTP API (I'm using the new version of Firebase presented at Google I/O 2016).
My understanding so far is that the specific type of write I'd like to accomplish is made with a POST request to a URL of this type:
https://my-project-id.firebaseio.com/{path-to-resource}.json
What I'm missing is the auth part: if I got it correctly a JWT should be passed in the HTTP Authorization header as Authorization : Bearer {token}.
So I created a service account, downloaded its private key and used it to generate the JWT, added it to the request headers and the request successfully wrote to Firebase DB.
Now the JWT has expired and any similar request to the firebase DB are failing.
Of course I should generate a new token but the question is: I wasn't expecting to handle token generation and refresh myself, most HTTP APIs I'm used to require just a static api key to be passed in the request so my webapps could be kept relatively simple by just adding the stati api key string to the request.
If I have to take care of token generation and expiration the webapp logic needs to become more complex (because I'd have to store the token, check if it is still valid and generate a new one when not), or I could just generate a new token for every request (but does this really make sense?).
I'd like to know if there's a best practice to follow in this respect or if I'm missing something from the documentation regarding this topic.
Thanks,
Marco
ADDENDUM
This is the code I'm currently running:
import requests
import json
from oauth2client.service_account import ServiceAccountCredentials
_BASE_URL = 'https://my-app-id.firebaseio.com'
_SCOPES = [
'https://www.googleapis.com/auth/userinfo.email',
'https://www.googleapis.com/auth/firebase.database'
]
def _get_credentials():
credentials = ServiceAccountCredentials.from_json_keyfile_name('my_service_account_key.json', scopes=_SCOPES)
return credentials.get_access_token().access_token
def post_object():
url = _BASE_URL + '/path/to/write/to.json'
headers = {
'Authorization': 'Bearer '+ _get_credentials(),
'Content-Type': 'application/json'
}
payload = {
'title': title,
'message': alert
}
return requests.post(url,
data=json.dumps(payload),
headers=headers)
Currently for every request a new JWT is generated. It doesn't seem optimal to me. Is it possible to generate a token that doesn't expire?
Thanks for the code example. I got it working better by using the credentials.authorize function which creates an authenticated wrapper for http.
from oauth2client.service_account import ServiceAccountCredentials
from httplib2 import Http
import json
_BASE_URL = 'https://my-app-id.firebaseio.com'
_SCOPES = [
'https://www.googleapis.com/auth/userinfo.email',
'https://www.googleapis.com/auth/firebase.database'
]
# Get the credentials to make an authorized call to firebase
credentials = ServiceAccountCredentials.from_json_keyfile_name(
_KEY_FILE_PATH, scopes=_SCOPES)
# Wrap the http in the credentials. All subsequent calls are authenticated
http_auth = credentials.authorize(Http())
def post_object(path, objectToSave):
url = _BASE_URL + path
resp, content = http_auth.request(
uri=url,
method='POST',
headers={'Content-Type': 'application/json'},
body=json.dumps(objectToSave),
)
return content
objectToPost = {
'title': "title",
'message': "alert"
}
print post_object('/path/to/write/to.json', objectToPost)

Python Requests - Azure Graph API Authentication

I am trying to access the Azure AD Graph API using the Python requests library. My steps are to first get the authorization code. Then, using the authorization code, I request an access token/refresh token and then finally query the API.
When I go through the browser, I am able to get my authorization code. I copy that over to get the access token. However, I've been unable to do the same with a Python script. I'm stuck at the part where I get the authorization code.
My script returns a response code of 200, but the response headers don't include that field. I would've expected the new URL with the code to be in the response headers. I would have also expected a response code of 301.
Does anyone know why my response headers don't have the auth code? Also, given the auth code, how would I pull it out to then get the access/refresh tokens using Python?
My code is below:
import requests
s = requests.Session()
s.auth = (USERNAME, PASSWORD)
# Authorize URL
authorize_url = 'https://login.microsoftonline.com/%s/oauth2/authorize' % TENANT_ID
# Token endpoint.
token_url = 'https://login.microsoftonline.com/%s/oauth2/token' % TENANT_ID
payload = { 'response_type': 'code',
'client_id': CLIENT_ID,
'redirect_uri': REDIRECT_URI
}
request = s.get(authorize_url, json=payload, allow_redirects=True)
print request.headers
It looks that you are implementing with Authorization Code Grant Flow via python requests. As the flow shows, the response of the request of authorize_url will redirect to a SSO page of your AD tenant. After your user login on, it will redirect to the location which set in redirect_uri with code as the URL parameters. E.G. http://localhost/?code=AAABAAAAiL...
And your code seems cannot simply display a html page with JavaScript allowed, so it will not redirect to the login on page.
So you can refer to # theadriangreen’s suggestion to implement with a python web server application.
Otherwise, you can refer to Microsoft Azure Active Directory Authentication Library (ADAL) for Python, which is a python package for acquiring access token from AD and can be easily integrated in your python application.

Categories

Resources