API authentication with python request - python

I am testing some APIs whose only documentation is the response to the requests for the respective APIs. Basically when I execute I get for all the requests: {"detail":"Authentication credentials were not provided."} except for the login request which is successful, this is because I obviously pass the parameters to it as required I guess.
Below is my code for the requests:
import requests
credential = {'identity' : 'xxxxxxx', 'password': 'xxxxxx'}
#use the 'auth' parameter to send requests with HTTP Basic Auth: auth = ('xxxxxx', 'xxxxxxx')
#url list
api_login = 'https://xxxxxxxx/api/login'
api_channel = 'https://xxxxxxxx/api/channel'
#requests
r_login = requests.post(url=api_login, data = credential)
print(r_login.status_code)
r_channels = requests.get(url=api_channel)
print(r_channels.text)
If it can help, following the info for the API that fail the authentication:
Curl
curl -X 'GET' \
'https://xxxxxxx/api/channels' \
-H 'accept: application/json' \
-H 'X-CSRFToken: xxxxxxxxx'
Request URL
https://xxxxxxx/api/channels
At the moment I've tried using basic authentication in the GET request and passing the headers in the documentation curl but as I'm not a bit practical I might have got it wrong.

Related

Receive Indeed API Access Token [Python]

I am trying to get the Indeed vacanties of my company via API with python. I am following https://developer.indeed.com/docs/authorization/3-legged-oauth and https://mathiashaentjens.medium.com/how-do-you-extract-data-using-the-indeed-api-and-build-your-own-indeed-campaign-reporting-8127252ef073.
I create Indeed API keys and recevive the Authorization Code. But i couldnt get Access Token. I send the same POST as documents via curl and python requests but i got this error;
{'error_description': 'Your request might include sensitive information passed in the URL query string. Parameters must be passed in the HTTP request body using the application/x-www-form-urlencoded format (See https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.3). For increased security, we recommend that you periodically rotate your application secret at https://secure.indeed.com/account/apikeys.', 'error': 'invalid_request'}
My python code is like;
headers = {'content-type': 'application/x-www-form-urlencoded','accept':'application/json'}
payload = {'code':'XXXX', 'client_id':'XXXX', 'client_secret':'XXXX', 'redirect_uri': 'http://localhost', 'grant_type':'authorization_code'}
response = requests.post('https://apis.indeed.com/oauth/v2/tokens', params=urllib.parse.urlencode(payload), headers=headers)
response.json()
and via command line;
curl -X POST -H "Content-Length: 0" -H "Content-Type: application/x-www-form-urlencoded" -H "Accept: application/json" "https://apis.indeed.com/oauth/v2/tokens?code=XXXX&client_id=XXXX&client_secret=XXXX&redirect_uri=http://localhost&grant_type=authorization_code"
Is there anyone familiar with this error?

How do you get and use a Refresh Token for the Dropbox API (Python 3.x)

As the title says, I am trying to generate a refresh token, and then I would like to use the refresh token to get short lived Access tokens.
There is a problem though, in that I'm not smart enough to understand the docs on the dropbox site, and all the other information I've found hasn't worked for me
(A, B, C) or is in a language I don't understand.
I have tried out all three examples from the github page, as well as user code from other questions on this site.
I haven't got anything to work.
The most I got was
Error: 400 Client Error: Bad Request for url: api.dropboxapi.com/oauth2/token
and
dropbox.rest.RESTSocketError: Error connecting to "api.dropbox.com": [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1123)
:(
Here is how I did it. I'll try to keep it simple and precise
Replace <APP_KEY> with your dropbox app key in the below Authorization URL
https://www.dropbox.com/oauth2/authorize?client_id=<APP_KEY>&token_access_type=offline&response_type=code
Complete the code flow on the Authorization URL. You will receive an AUTHORIZATION_CODE at the end.
Go to Postman and create a new POST request with below configuration
Request URL- https://api.dropboxapi.com/oauth2/token
Authorization -> Type = Basic Auth -> Username = <APP_KEY> , Password = <APP_SECRET>
(Refer this answer for cURL -u option)
Body -> Select "x-www-form-urlencoded"
Key
Value
code
<AUTHORIZATION_CODE>
grant_type
authorization_code
After you send the request, you will receive JSON payload containing refresh_token.
{
"access_token": "sl.****************",
"token_type": "bearer",
"expires_in": 14400,
"refresh_token": "*********************",
"scope": <SCOPES>,
"uid": "**********",
"account_id": "***********************"
}
In your python application,
import dropbox
dbx = dropbox.Dropbox(
app_key = <APP_KEY>,
app_secret = <APP_SECRET>,
oauth2_refresh_token = <REFRESH_TOKEN>
)
Hope this works for you too!
The previous answer worked as a charmed, but if you need something quick to run, you can use this snippet:
#/bin/bash
echo -n "Enter APP_KEY"
read APP_KEY
echo -n "Enter APP_SECRET"
read APP_SECRET
BASIC_AUTH=$(echo -n $APP_KEY:$APP_SECRET | base64)
echo "Navigate to URL and get ACCESS CODE"
echo "https://www.dropbox.com/oauth2/authorize?client_id=$APP_KEY&token_access_type=offline&response_type=code"
echo -n "Return to this script once you have the ACCESS_CODE"
read DUMMY
echo -n "Enter the ACCESS_CODE"
read ACCESS_CODE_GENERATED
curl --location --request POST 'https://api.dropboxapi.com/oauth2/token' \
--header "Authorization: Basic $BASIC_AUTH" \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode "code=$ACCESS_CODE_GENERATED" \
--data-urlencode 'grant_type=authorization_code'
All methods above work, just want to post a pure python solution, which itself draws reference from the answers above.
Find the APP key and App secret from the App Console.
Run the following snippet (replace APP_KEY with the value
obtained from last step) and complete the process in the
browser to obtain Access Code Generated.
import webbrowser
APP_KEY = '<APP_KEY>'
url = f'https://www.dropbox.com/oauth2/authorize?client_id={APP_KEY}&' \
f'response_type=code&token_access_type=offline'
webbrowser.open(url)
Replace all APP_KEY, APP_SECRET, and ACCESS_CODE_GENERATED with the actual values in the following snippet. Run the snippet.
import base64
import requests
import json
APP_KEY = '<APP_KEY>'
APP_SECRET = '<APP_SECRET>'
ACCESS_CODE_GENERATED = '<ACCESS_CODE_GENERATED>'
BASIC_AUTH = base64.b64encode(f'{APP_KEY}:{APP_SECRET}'.encode())
headers = {
'Authorization': f"Basic {BASIC_AUTH}",
'Content-Type': 'application/x-www-form-urlencoded',
}
data = f'code={ACCESS_CODE_GENERATED}&grant_type=authorization_code'
response = requests.post('https://api.dropboxapi.com/oauth2/token',
data=data,
auth=(APP_KEY, APP_SECRET))
print(json.dumps(json.loads(response.text), indent=2))

How can I get the data from an API using Python Request Post?

I'm trying to retrive some data from apptopia but I'm finding it pretty tricky (due to my lack of experience). In their authentication page: https://dev.apptopia.com/#authentication there are some instructions, but I just can't make it work.
I need a client and a secret (these bellow are not mine but the ones on the company's site)
client: JFqXPDhiLuvY
secret: L2nerprCksacBoFzUqtfHz8v
And I must use those information in order to obtain a Session token via HTTPS POST request:
curl -X "POST" "https://integrations.apptopia.com/api/login" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "client=<client>" \
--data-urlencode "secret=<secret>"
I just don't know how to do it. I tried using the answen on this post: Python Request Post with param data but it didn't work. Could someone help me please? Thanks!
Did you try passing credentials as data in your request?
import requests
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
}
data = {
'client':your_client,
'secret':your_secret'
}
response = requests.post('https://integrations.apptopia.com/api/login', headers=headers, data=data)

Heroku API returns 403 in Python only

So I am working on a Python script to communicate with the Heroku API to get dyno information, but it doesn't seem to work in Python. However, with the exact same information, it works fine in cURL:
Works (cURL 7.51.0):
curl -XGET -H 'Authorization: Bearer <BEARER>' -H 'Accept: application/vnd.heroku+json; version=3' 'https://api.heroku.com/apps/<APP>/dynos/<DYNO>'
Fails (Python, both on 2.7.12, 3.5.3, and 3.6.1):
import json
import requests
callapi = requests.get('https://api.heroku.com/apps/<APP>/dynos/<DYNO>', headers={"Authorization":"Bearer <BEARER>", "Accept":"application/vnd.heroku+json; version=3"})
json = callapi.json()
print(json)
...with error:
{'id': 'forbidden', 'message': 'You do not have access to the app <APP>.'}
Where <APP> is my app name, <DYNO> is the dyno name, and <BEARER> is my bearer token.
Any help would be appreciated!
The problem is that requests uses the .netrc file if no auth argument is provided: http://docs.python-requests.org/en/master/user/authentication/?highlight=netrc#netrc-authentication
So requests is using your Heroku credentials (heroku login saves your credentials in that file).
An easy way to fix the issue is expained here: http://docs.python-requests.org/en/master/user/authentication/?highlight=netrc#new-forms-of-authentication
TL;DR: remove the Authorization header and use the auth parameter with a custom class.
This is the implementation I'm using:
class HerokuBearerAuth(requests.auth.AuthBase):
def __init__(self, api_key):
self.api_key = api_key
def __call__(self, r):
r.headers.update({'Authorization': 'Bearer {}'.format(self.api_key)})
return r
myHeaders = {'Accept': 'application/vnd.heroku+json; version=3'}
response = requests.get(myUrl, headers=myHeaders, auth=HerokuBearerAuth(api_key))

Rest API authentication and access using Python Requests

I have been regularly accessing an API at work using curl. But now i need to do a bit of automation for the same.
Was trying to translate what i do with curl into python using the requests module.
But I keep receiving a 401 error.
My curl requests that i regularly are as below:
Step1: Session Authentication with cookies:
curl -b cookies -c cookies -v -X POST -H "Content-Type: application/json" --data-binary '{"auth":{"username":"aaa","password":"bbb"}}' http://api.xyz.at/auth
Step2: Access API URL for data retrieval
curl -b cookies -c cookies http://api.xyz.at/somepage?per_id=556677
Now using Python Requests, here is what I am doing
Step1: For Authentication
username = 'aaa'
password = 'bbb'
s = requests.Session()
s.post('http://api.xyz.at/auth',auth=('username','pasword'))
This "i think" works fine, and give me the below response
<Response [200]>
Step2: Access API URL for data retrieval
s.get('http://api.xyz.at/somepage?per_id=556677')
but this Step 2 keeps returning an error
<Response [401]>
The code is failing and not sure where.
My Python skills are visibly pedestrian. I have been looking at the Requests website. But unfortunately haven't been able to decipher.
Guidance would be appreciated :)
import urllib2, urllib
url = 'http://api.xyz.at/auth'
pm = urllib2.HTTPPasswordMgrWithDefaultRealm()
pm.add_password(None, url, 'user', 'password')
auth = urllib2.HTTPBasicAuthHandler(pm)
opener = urllib2.build_opener(auth)
urllib2.install_opener(opener)
request = urllib2.Request('http://api.xyz.at/somepage?per_id=556677', None)
handler = urllib2.urlopen(request)
handler.read()
Since you are getting a 401 error I guess you are not passing the authentication token which you get as response from login API. Use the same auth token to perform other options - Get-post-Delete.

Categories

Resources