How to use Udemy api using requests module in python - python

I am trying to fetch some data from the udemy api. When I put a GET a request I get 403 status code
What I tried:
import requests
headers = {
'Authorization': 'Basic {BASE64_ENCODED(CLIENT_ID:CLIENT_SECRET)}',
}
response = requests.get('https://www.udemy.com/api-2.0/courses/', headers=headers)
I also tried using base64encode and using auth but that too didn't work.
According to Udemy,
To send authenticated requests, provide the client_id and client_secret values as a base64 encoded HTTP Authorization header.
curl --user {YOUR_CLIENT_ID}:{YOUR_CLIENT_SECRET} https://www.udemy.com/api-2.0/courses/
curl -H "Authorization: Basic {BASE64_ENCODED(CLIENT_ID:CLIENT_SECRET)}" https://www.udemy.com/api-2.0/courses/
Thanks in advance for your help guys!

well, that's because you're sending a string that says:
"Basic {BASE64_ENCODED(CLIENT_ID:CLIENT_SECRET)}"
you're not passing actual base64 encoded parameters.
for starters import base64 then use it to encode YOUR client_id and YOUR client_secret, you should be able to figure out how to obtain those fron Udemy's API documentation, ultimately it should look something like this:
import requests
import base64
client_id = <client_id you obtain from Udemy>
client_secret = <client_secret you obtain from Udemy>
client_id_secret = f"{client_id}:{client_secret}"
b64_client_id_secret = base64.encode(client_id_secret)
headers =
{
'Authorization': f'Basic {b64_client_id_secret}'
}

Related

Python API request to internal API with OKTA Authentication

I used to selenium for downloading special reports from webpage where I have to login. Webpage has integrated OKTA Authentication plugin . I find out that there would be better and more effective use internal API requests. So I tried find how to use request python library with creating session, but I am unsuccessful. I tried this code, but it ends with 400 error.
payload = {"password":"password","username":"username","options":{"warnBeforePasswordExpired": True,"multiOptionalFactorEnroll": True}}
with requests.Session() as s:
p = s.post('https://sso.johndeere.com/api/v1/authn', data=payload)
r = s.get("requested_url")
print(p)
I am unable get throw auth. Has anybody experience with breaking OKTA auth plugin using requests library?
Thanks
Best Regards
Merry Christmas and Welcome to Stackoverflow!
Firstly, an HTTP error code of 400 error means one or more settings is wrong at the client side. You can learn more about it here.
You seem to be missing out important headers configuration. You need to set the content-type header correctly otherwise the destination server won't be able to process your data.
Also, as a bonus point. You need to format your payload into a valid JSON string before sending out the request too.
import requests
import json
# Setup proper headers
headers = {
"accept": "application/json, text/plain, */*",
"content-type": "application/json; charset=UTF-8"
}
# Your body data here
payload = {"password":"password","username":"username","options":{"warnBeforePasswordExpired": True,"multiOptionalFactorEnroll": True}}
payload_json = json.dumps(payload) # Format it into a valid JSON str
with requests.Session() as s:
p = s.post('https://sso.johndeere.com/api/v1/authn', headers=headers, data=payload_json)
r = s.get("requested_url")
print(p.content)

How to get API answer with an API key using the requests package in Python

How to get http request from API organized around REST, JSON is returned by all API responses. All ressources have support for bulk fetches via "list" API methods
Here is what I have as documentation:
# With shell, you can just pass the correct header with each request
curl "https://www.api_url.com/api/dispute?page=1&limit=5"
-H "Authorization: [api_key]"
# Query Parameters:
# page 1 The cursor used in the pagination (optional)
#limit 10 A limit on the number of dispute object to be returned, between 1 and 100 (optional).
I don't know how to interpret this in python and to pass api_key to extract the data from this object dispute
import requests
import json
response = requests.get("https://api_url.com/")
The -H option in curl sets a header for the request.
For a request using requests, you can set extra headers by passing a keyword argument headers.
import requests
import json
response = requests.get(
"https://www.api_url.com/api/dispute",
headers={"Authorization" : "<api_key_here>"}
)
You can also add your parameters easily if needed
response = requests.get(
"https://www.api_url.com/api/dispute",
headers={"Authorization" : "<api_key_here>"},
params={
"page": 1,
"limit":1
}
)
If you want to make multiple requests, you can look into using a requests.Session. Session Tutorial
It will allow you to set the header centrally.
You can also use an Auth Handler to manage authentication.
You can use the curlconverter tool to simplify the translation to Python code:
For the provided curl input:
curl "https://www.api_url.com/api/dispute?page=1&limit=5" \
-H "Authorization: [api_key]"
Here is the result in Python. Note that I've changed params to a dict object, as it's easier to work with dictionaries in Python. It doesn't matter if the values for any of the query params are a type other than str, as they will simply be concatenated in the URL string when making the request.
import requests
headers = {
'Authorization': '[api_key]',
}
params = {
'page': 1,
'limit': 5
}
response = requests.get('https://www.api_url.com/api/dispute',
headers=headers, params=params)

Unable to get response from FreshDesk API in proxy mode {"code" : "invalid_credentials", "message" : "You need to be logged in to perform action"}

So I'm using FreshDesk API and able to get the response using request module, But whenever I'm using proxy servers I'm unable to get the response.
import base64
import requests
import os
from requests.auth import HTTPBasicAuth
import ssl
method = "get"
url = "https://mycompanydomain.freshdesk.com/api/v2/tickets"
apiKey = "XXXXXXXXX"
secret = "x"
os.environ["REQUESTS_CA_BUNDLE"] = "Path to CA Certs"
auth = HTTPBasicAuth(apiKey, secret)
rsp = requests.request(method, url, headers=None, auth=auth)
print(rsp.text)
But whenever I'm using the proxy server in my organization, I'm getting an error message as {"code":"invalid_credentials","message":"You have to be logged in to perform this action."}
Code which I'm using for the proxy servers
import base64
import requests
import http.client
import urllib.parse
method = "get"
apiKey = "XXXXXXXX"
secret = "x"
url = "https://mycompanydomain.freshdesk.com/api/v2/tickets"
cred= '{}:{}'.format(apiKey, secret)
cred = base64.b64encode(cred.encode('utf-8')).decode('utf-8')
authorization_headers = {
'Proxy-Authorization': 'Basic {}'.format(cred)
}
conn = http.client.HTTPSConnection("11.125.250.121", 3128)
conn.set_tunnel("mycompanydomain.freshdesk.com", headers = authorization_headers)
headers = { 'Content-Type' : 'application/json' }
conn.request("GET", "/api/v2/tickets",headers = headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
FreshDesk API Docs for using their API
curl -v -u abcdefghij1234567890:X -H "Content-Type: application/json" -X GET 'https://domain.freshdesk.com/api/v2/tickets'
Any possible way to resolve this error?
Here is a bit of a guess, I haven't actually tried it but I do use Freshdesk, and I should be using their API.
Here is a link to the Freshdesk API:
https://support.freshdesk.com/support/solutions/articles/216548-create-and-update-tickets-with-custom-fields-using-api
I would try to taking out the "-H "Content-Type: application/json" to better match the suggested code. I would add the Content Type for POSTS not GETs in most cases, unless the API specifically calls for it. Try it and let us know how it works.
curl -u API_KEY:X -X GET https://domain.freshdesk.com/api/v2/ticket_fields
Encoding the api key with the x for example as follows: someapikey:x helps.
See link:
How do I encode and decode a base64 string?
Also see FreshDesk api doc:
https://developers.freshdesk.com/api/#authentication
See the Note which says Encode if plain api key does not work.

Python 2.7 HTTP Basic Authentication

maybe someone can help me with this. I'm trying to get a data from a website using Python 2.7, using HTTP Basic Authentication.
The only instructions the website provides is this:
In order for your web service client to authenticate using basic
authentication, the first HTTPS request must include the
"Authorization" header specifying the account credentials to
authenticate with. The header for a such a request would look like
this:
GET /polcs/trade.xml HTTP/1.0
Host: secure.pol.com
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
I tried few things but neither of them works, for example:
import urllib2
import base64
b = base64.encodestring('USERNAME:PASSWORD').replace('\n', '')
conf = {'headers': {'GET': '/polcs/trade.xml HTTP/1.0', 'Authorization': 'Basic ' + b},
'url': 'secure.pol.com'}
datas = None
request = urllib2.Request(conf['url'], datas, conf['headers'])
result = urllib2.urlopen(request)
This one gives me HTTP Error 403:
url = 'https://secure.pol.com/polcs/data.xml'
request = urllib2.Request(url)
b = base64.encodestring('USERNAME:PASSWORD').replace('\n', '')
request.add_header("Authorization", "Basic " + b)
result = urllib2.urlopen(request)
Can someone please tell me where do I make a mistake trying to get that data?
Thank you!

Received Authentication Denied as Response while trying to get the access token (for Cloudhub.io) with requests library

I'm tying to get the data from the Cloudhub API which resides on Mulesoft.
I tried to access through postman (With the same Client Credentials - Bearer Authorization) and it's working fine (I can able to get the result with proper get requests).
But when I tried to do the same with Python requests library I ran into issues. Here is my piece of code:
import requests
import json, os
CLIENT_ID = os.environ['CLIENT_ID']
CLIENT_SECRET = os.environ['CLIENT_SECRET']
grant_type = 'client_credentials'
body_params = {'grant_type' : grant_type}
headers = {'Accept': '*/*',
'Cache-Control':'no-cache',
'Accept-Encoding': 'gzip, deflate',
'Content-Type':'application/json, application/x-www-form-urlencoded',
'Connection': 'keep-alive'}
url='https://<domain-name>-api.us-w2.cloudhub.io/api/token'
response = requests.post(url, data=body_params, auth = (CLIENT_ID, CLIENT_SECRET), headers= headers)
token_raw = json.loads(response.text)
print(token_raw)
Result: {'error': 'Authentication denied.'}
All I need to know is
How it's working fine with Postman but why I'm not able to connect with python code?
Is there anything I've to change in my code or any additional information needed for this request? or am I passing the correct endpoint in receiving the access token for Cloudhub API?
Please post your suggestions or any documentation that I need to refer.
Hope the information that I gave is clear and Thanks in Advance !!
I found the answer of my own question. I can get it from the postman itself.
Here is my code for API Call with Python.
import http.client
import os
conn = http.client.HTTPSConnection("<domain-name>-api.us-w2.cloudhub.io")
payload = ''
headers = {
'client_id': os.environ['CLIENT_ID'],
'client_secret': os.environ['CLIENT_SECRET']
}
conn.request("GET", "/api/<Query that you want to pass - endpoint>", payload, headers)
response = conn.getresponse()
resp_data = response.read()
print(resp_data.decode("utf-8"))
The URL is incorrect. To call CloudHub REST API you need to obtain a bearer token from Anypoint Platform REST API. The URL mentioned looks to for some application deployed in CloudHub, not from the platform APIs. This is the same method than to get the bearer token to use in Anypoint MQ Admin API. It looks like you are trying to use the Anypoint MQ Broker API, which is an Anypoint MQ specific token.
Example in Curl to get an Anypoint Platform token:
$ curl -H "Content-Type: application/json" -X POST -d '{"username":"joe.blogs","password":"sample.password"}' https://anypoint.mulesoft.com/accounts/login
{
"access_token": "f648eea2-3704-4560-bb46-bfff79712652",
"token_type": "bearer",
"redirectUrl": "/home/"
}
Additionally the Content-type of your example seems incorrect because it has 2 values.
I'm sure the Postman request is different for it to work, or maybe it works only for the Anypoint MQ Broker API.

Categories

Resources