I'm trying to use Streamlabs API. Streamlabs API uses Oauth2 for creating apps. So first I send whoever's using my app to an authorization link containing my app's client id and the scopes I want to use.
(Something like this: streamlabs.com/api/v1.0/authorize?client_id=CLIENT-ID-HERE&redirect_uri=REDIRECT-URI&response_type=code&scope=SOME+SCOPES+HERE)
Once I've done that I receive a code at the redirect uri specified. I then use that code to get the access token for permanent access to the connected user's account. I then receive the access token from a POST request that works perfectly... Now I run into the problem. When getting the temporary code before the access token I specified the scopes: "donations.read +donations.create+alerts.write+alerts.create".
When authorizing, the app asks for permission to the different scopes. The scope in focus is "alerts.write" so that I can send test alerts using POST requests. But this doesn't work for some reason. To send a test alert I have to send a POST request to this url: "https://streamlabs.com/api/alerts/send_test_alert"
I've tried doing that in two different ways.
1:
import requests
url = "https://streamlabs.com/api/alerts/send_test_alert"
data = {
"access_token":"UserAccessTokenHere",
"type":"donation"
}
response = requests.post(url=url, data=data)
print(response.text)
2:
import requests
url = "https://streamlabs.com/api/alerts/send_test_alert?access_token=UserAccessTokenHere&type=donation"
response = requests.post(url=url)
print(response.text)
If I do print(response) it prints "Response [405]".
But if I do print(response.text) I get a long HTML document for this page: Error response page
Any ideas what's going wrong with my Python requests? send_test_alert documentation here: Link
I've contacted support and looks like you've made the same error as me.
You're not actually sending a request to the right URL.
You are a sending a request to: "https://streamlabs.com/api/alerts/send_test_alert"
You should be using the URL: "https://streamlabs.com/api/v1.0/alerts/send_test_alert"
Related
I wonder if there is a way to authenticate each redirected URL when working with Python modules such as httpx or requests?
Problem Statement
I am trying to connect to an API endpoint under the company network. Due to the company's cyber security measures, the API endpoint will be randomly masked with a company proxy, which causes the 307 Redirect status code.
my current code snippet looks like the below:
import httpx
api_url = 'https://demo.vizionapi.com/carriers'
head = {
'X-API-Key':'API KEY'
}
response = httpx.get(url=api_url, verify='supporting_files/cacert.pem',
headers=head, auth=('my username', 'my password'),
follow_redirects=True)
With above code, I received the 401 authentication needed error (But auth has been passed). This error will only happen when redirection occurs due to the company proxy.
Question:
My assumption is the authentication is only being passed into the first URL not the redirected URL. Therefore, I wonder if anyone know how I can use the same auth parameter for all URLs (direct & redirect)?
Any suggestion will be deeply appracaited.
I don't know what requests behavior with regards to auth during redirect is, but the first solution to come to mind is to manually follow the redirects yourself. Put your request in a loop that checks for the 3xx response codes, and handle auth however you want to.
I'm trying to do an authentication against Auth0 from a Python script using the PKCE authentication flow, and I'm getting an error that Auth0 can't see exactly one of my URI parameters.
<<CAPITAL LETTERS>> represent missing constants related to the authentication exchange being tested.
import requests
import urllib.parse
def process_auth_callback(authorization_code, callback_uri):
payload = {
'grant_type': 'authorization_code',
'client_id': <<AUTH CLIENT ID>>,
'code_verifier': <<CODE VERIFIER>>,
'code': authorization_code,
'redirect_uri': urllib.parse.quote(callback_uri)
}
r = requests.post('https://<<APP ID>>.us.auth0.com/oauth/token', data=payload)
print(r.request.body)
print(r.text)
process_auth_callback(<<AUTHORIZATION CODE>>, 'http://localhost:1234/login')
I get the error back from Auth0's API:
{"error":"unauthorized_client","error_description":"The redirect URI is wrong. You sent null//null, and we expected http://localhost:1234"}
However, the request body prints as the following: grant_type=authorization_code&client_id=<<AUTH CLIENT ID>>&code_verifier=<<CODE VERIFIER>>&code=<<AUTHORIZATION CODE>>&redirect_uri=http%253A%2F%2Flocalhost%253A1234%2Flogin
This appears to include the correct redirect URI, so I'm not sure why the API is reporting null//null. Is this an issue with how I'm using requests? Something else?
Ah, I found my own answer not long after.
The key is the %253A in the URI encoding in the outgoing request body. (See this answer) Python's requests library is already URI-encoding the parameters, so my URI encoded urllib.parse.quote(callback_uri) is then being encoded again during the data preprocessing prior to send. Auth0's API is unable to parse this and processes it as null//null.
Hi Stack Overflow community, thanks in advance for your help:
Question for Community:
Instead of reinventing the oauth wheel, are there any tips / best practices for creating my own oauth signature/nonce within my python GET requests for Netsuite's new API (REST Web Services; see below for context of question)? It seems that other folks who have been successful at this have done it through trial and error which is my plan as well, but ideally I'd like to have fewer errors and again, not reinvent the wheel. Any tips, tricks, ideas are greatly welcome. See context below
What:
Attempting to make a GET request using Netsuite's brand new REST API (REST Web Services). This is a different API than their SOAP/ RESTlets.
How:
Through writing Python script in Visual Studio Code. I am successful at making the request in Postman. I copied the code into Visual Studio Code that Postman used to make the successful GET request and received a 401 response (see below).
Problem Encountered:
I receive a 401 response, invalid login. There is no official Netsuite documentation on how make a successful interaction with this new REST API outside of Postman, so after reading through StackOverflow and other blogs/publications it seems that I need to create my own oauth_signature, oauth_timestamp, and oauth_nonce.
Postman GET Request Code:
import requests
url = "https://123456-sb1.suitetalk.api.netsuite.com/services/rest/query/v1/workbook/custworkbook12345/result"
payload = {}
headers = {
'Authorization': 'OAuth realm="123456_SB1",oauth_consumer_key="123456789101112131415",oauth_token="123456789101112131415",oauth_signature_method="HMAC-SHA256",oauth_timestamp="123456789",oauth_nonce="123456789",oauth_version="1.0",oauth_signature="123456789101112131415"',
'Cookie': 'NS_ROUTING_VERSION=LAGGING'
}
response = requests.request("GET", url, headers=headers, data = payload)
print(response.text.encode('utf8'))
Thanks in advance!
Thanks to Josh's recommendation (see comments to my original question) I successfully used oauthlib's oauth1 client to send a request in Visual Studio Code. The nonce and signature look a little different than what Postman shows in their code snippet, but it did work. For anyone attempting the same thing with Netsuite's REST Web Services I suggest going this route.
My code that sent a successful GET request:
import requests
import oauthlib.oauth1
import json
url = "https://12345-sb1.suitetalk.api.netsuite.com/services/rest/query/v1/dataset/custdataset1/result"
payload = {}
client = oauthlib.oauth1.Client('consumer key', client_secret='12345',
resource_owner_key='12345', resource_owner_secret='12345', realm='12345_SB1',signature_method="HMAC-SHA256")
url, headers, body = client.sign('https://4635201-sb4.suitetalk.api.netsuite.com/services/rest/query/v1/dataset/custdataset1/result')
response = requests.request("GET", url, headers=headers, data = payload)
print(response.text.encode('utf8'))
A Few Additional Helpful Notes -
I'm testing this in Netsuite Sandbox, hence the realm "12345_SB1". If
you aren't in sandbox you shouldn't need the underscore SB. Just use your account ID.
I'm pulling Netsuite Analytics Report, which at this time is still in
beta for the new API (REST Web Services).
I used the Python oauthlib that Josh recommended and I recommend you do the same, link here
I have been trying to use the Django-REST authentication to validate the user name /password given in a desktop app.
On the server side, I have installed the following DJANGO-REST-FRAMEWORK-JWT package found here:
https://github.com/GetBlimp/django-rest-framework-jwt
I have gone through the example and when I run the following on the command line get a token as a response:
curl -X POST -d "username=luca&password=letmein123" http://localhost:8000/api-token-auth/
And I get:
{"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InBhbmthaiIsInVzZXJfaWQiOjIsImVtYWlsIjoiIiwiZXhwIjoxNDc5MTE5NzQ2fQ.RA085m-YSnGFheykCCxSVxI_9rW9AC9kEaOkUB5Gm0A"}
I tried something like:
import requests
resp = requests.post('http://127.0.0.1:8000/api-token-auth/', data={}, auth=('luca', 'letmein123'))
However, this always returns response code 400 with Bad request
My question is how can I do that from my desktop python app. I basically want to call the same API with the username and passord and be able to process the response and access protected APIs.
The auth parameter of requests.request is by default meant for Basic/Digest/Custom HTTP Auth, analogous to the -u, --user <user:password> parameter of curl.
You could define your own custom Authentication class to achieve the desired result, but the basic way to achieve the same result as your original curl request is:
resp = requests.post(
'http://localhost:8000/api-token-auth/',
data={"username": "luca", "password": "letmein123"})
The data dictionary can alternatively be supplied as json by using the json parameter if you prefer (the request would be different, but also supported by Django REST framework JWT).
You can then use the token (extracted with token = resp.json()['token']) to access the restricted urls as following:
requests.post(
'http://localhost:8000/some-personal-function/',
json={"foo": 42},
headers={'Authorization': 'JWT ' + token})
By the way looking at response.text might help finding the reason, which would, in the case of your 400 response, contain the following:
'{"username":["This field is required."],"password":["This field is required."]}'
I have set up everything required for the foursquare push api, including a secure server.
Now my question is what do I need to do to get data from that request and display on my web page. Foursquare API sends a POST to a URL which I can handle with a view.
Do I need to use AJAX calls, or just handle the post request in a view and update something in the database and show data from that database with ajax.. open to suggestions.
No, all you need to do is send requests and receive responses. Please take a look at this -> python-requests.org -> The documentation provided how you can send and receive requests.
So, for example, you could send a POST request like so:
r = requests.get('https://api.github.com/user', <your arguments here>)
And now r would contain the POST response from the said url.