When PUTting to a playlist on Soundcloud's API, the playlist doesn't actually get updated? - soundcloud

When I try to HTTP PUT a SoundCloud playlist through the API, with a data structure: {"tracks": [{"id": 12345}, {"id": 45678}]}, the playlist doesn't get updated. The API returns a 200 response with what was in the playlist, completely ignoring the modifications.
What I think might be wrong
The SoundCloud API doesn't accept that format of data
Somehow the authorization is invalid, even though it's returning a 200
The code:
import requests
playlist_url = 'https://api.soundcloud.com/playlists/XXXXX?client_id=XXXXX'
like_url = 'https://api.soundcloud.com/users/XXXXX/favorites?client_id=XXXXX'
likes = requests.get(like_url)
likes_json = likes.json()
# oauth2_token = requests.post('https://api.soundcloud.com/oauth2/token', data=opts).json()
oauth2_token = 'XXXXX'
playlist = {'tracks': []}
for like in likes_json[::-1]:
track_id = like['id']
playlist['tracks'].append({'id': track_id})
resp = requests.put('https://api.soundcloud.com/playlists/XXXXX', json=playlist, params={
'oauth_token': oauth2_token,
'client_id': 'XXXXX',
'client_secret': 'XXXXX'
})

It turns out I was simply sending the wrong data structure. It should have been {'playlist': {'tracks': [{'id': 1234}, {'id': 4567}]}}.
https://stackoverflow.com/a/28847716/2350164

Related

Bad gateway on dataprep job run api

previously same api was working fine but now it shows 502 bad gateway. Here is my api call:
def hit_dataprep_job(receipe_id):
print(receipe_id)
url = "https://api.clouddataprep.com/v4/jobGroups"
body = json.dumps({"wrangledDataset": {"id": receipe_id}})
headers = {"Content-Type": "application/json","Authorization": "Bearer "+str(key)}
response = requests.post(url, data=body, headers=headers)
print(response)
print(response.json())
if response.json()['reason'] == 'JobStarted':
print('started job successfully')
Output:
<Response [502]>
{'code': 13, 'message': 'BAD_GATEWAY', 'details': [{'#type': 'type.googleapis.com/google.rpc.DebugInfo', 'stackEntries': [], 'detail': 'application'}]}
this incident is now resolved. You can subscribe to https://status.trifacta.com/ for the latest update.
Join discussions and collaborations with Dataprep users in our Community, https://community.trifacta.com/s/.

Flask JWT Extended- Different locations for access_token (header) & refresh_token(httpOnly cookie)

How to configure flask app with flask-jwt-extended for which we need something like below.
AccessToken/Bearer must sent as a Header (and not cookie)
RefreshToken must sent as httpOnlyCookie for /api/refreshtoken path only
How to set two different token one in header and one in cookie? We are able to set either both as cookie or both as a header.
Any help?
Thanks
Raxit
I wanted to do the same while building a React + Flask single page application after days of headache trying to understand authorization and authentication as I am a beginner.
Anyways, I managed to do it this way:
In Flask, config:
app.config['JWT_TOKEN_LOCATION'] = ['headers', 'cookies']
app.config['JWT_REFRESH_COOKIE_PATH'] = '/auth/refresh'
And what I return in my login function:
resp = jsonify({'access_token': access_token})
set_refresh_cookies(resp, refresh_token)
return resp, 200
And in my refresh function:
# Refresh access token
#app.route('/auth/refresh', methods=['POST'])
#jwt_refresh_token_required
def refresh():
user = get_jwt_identity()
resp = {
'access_token': create_access_token(
identity={
'username': user['username'],
'role': user['role']
},
expires_delta=timedelta(seconds=600),
user_claims=user['role']
)
}
return jsonify(resp), 200
And on the front side, I collect the JSON access_token and set it in memory and use withCredentials to send the refresh_token with my API calls.
axios.defaults.withCredentials = true;
axios.defaults.headers.common['Authorization'] = `Bearer ${access_token}`;
more precisely:
.then(({ data: { access_token } }) => {
axiosHttp.defaults.headers.common['Authorization'] = `Bearer ${access_token}`;
return jwt_decode(access_token);
})
then I use the data from my decoded access_token in a React Context Component to authenticate access to pages depending on roles.
logout is simply setting to null my context and calling the api to unset the refresh cookie
#app.route('/auth/logout', methods=['DELETE'])
#jwt_required
def logout():
resp = jsonify({"msg": "Successfully logged out"})
unset_jwt_cookies(resp)
return resp, 200
it's quite simple in the end but it took me quite a while to figure out!

facebook api graph not search users

I'm trying to find users but it throws me an authentication error
import requests
from urllib.parse import urlencode
token = 'my-token'
graph_url = 'https://graph.facebook.com/v3.2/search?'
params = {
'q':'francisco',
'type':'user',
'method':'get',
'format':'json',
'access_token':token
}
url = graph_url+urlencode(params)
resp = requests.get(url)
print(resp.json())
error:
{'error': {'message': 'Unsupported operation', 'type': 'OAuthException', 'code': 100, 'fbtrace_id': 'Dao1UbelGkF'}}
It seems that something I'm not doing well or that searches are no longer allowed
https://developers.facebook.com/docs/graph-api/changelog/breaking-changes#search-4-4
Searching for users is not available anymore since 2018. It would not make any sense anyway, you would only be able to get users who authorized your App.

GCS Signed URL Post Object using XMLHttpRequest with progress listener results in browser sending Options instead of POST

I have successfully implemented upload of an Object using multi-part Post request with Signature, Policy document GCS POST ...etc from the browser using XMLHttpRequest and angular $http .
But when I attach event listener on XMLHttpRequest upload to show a progress bar to the user, the browser sends a Options Method instead of POST. storage.googleapis.com returns 200 ok After that I was expecting a POST to be sent from the browser with the file but that did not happen. Without the upload listener the code works perfectly. Should I move to PUT ? any workaround
factory.uploadFileToUrlXHR = function(file,obj){
var deferred = $q.defer();
var fd = new FormData();
fd.append('key', obj.key);
fd.append('Content-Type',obj.contenttype)
fd.append('GoogleAccessId', obj.googleaccessId);
fd.append('policy', obj.policy);
fd.append('signature', obj.signature);
fd.append('file', file);
var XHR = new XMLHttpRequest();
XHR.addEventListener('load', function(event) {
// alert('Yeah! Data sent and response loaded.');
deferred.resolve(event);
});
XHR.upload.addEventListener("progress",function(evt){
if (evt.lengthComputable) {
$log.info("add upload event-listener" + evt.loaded + "/" + evt.total);
}
}, false);
// Define what happens in case of error
XHR.addEventListener('error', function(event) {
//alert('Oups! Something went wrong.');
deferred.resolve(event);
});
// Set up our request
XHR.open('POST', obj.uri);
// Send our FormData object; HTTP headers are set automatically
XHR.send(fd);
return deferred.promise;
}
I resolved the issue ,
When you use POST from the browser to upload a file to Google Cloud storage append the bucket name to the URL . In the below code obj.uri should be "https://storage.googleapis.com/bucketname
XHR.open('POST', obj.uri); and remove the bucket name from the key. Key should contain the object name.
fd.append('key', obj.key);
if you do not append the bucket name as part of the POST URL, the browser will send the Options request to https://storage.googleapis.com/. GCS will not be able to find the right CORS configuration. CORS configuration is mapped to the bucket Name.
Sample CORS configuration i had applied.
[
{
"origin": ["http://localhost:8282"],
"method": ["OPTIONS","PUT","POST","GET", "HEAD", "DELETE"],
"responseHeader": ["Content-Type"],
"maxAgeSeconds": 3600
}
]

Gerrit set-review api doesn't work

I tried to add review comments by using this "set-review" api:
https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#set-review
I can get a json response from this interface, but nothing is changed.
I can't see any new comments from Gerrit web page.
Here is the example of my client side code:
url = '/changes/16148/revisions/1/review'
data = json.dumps({
'message': 'test',
'labels': {},
'comments': {
'tools/docpreview.py': [{
'line': 20,
'message': 'hehe',
}],
},
'notify': 'NONE'
})
pprint(rest.post(url, data=data))
And the response example(Private info was deleted).
This response looks like result of get-review api described here:
https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#get-review
{u'_number': 16148,
...
u'insertions': 20,
u'kind': u'gerritcodereview#change',
u'created': u'2014-11-05 16:23:08.849000000',
...
u'status': u'NEW',
u'subject': u'Add markdown preview.',
u'updated': u'2014-11-05 22:02:32.978000000'}
I struggled with getting this right for a while, finally, the following piece of code in Python works for me:
from requests.auth import HTTPBasicAuth
from pygerrit2.rest import GerritRestAPI
REST_AUTH = HTTPBasicAuth(MISC['auth_username'], MISC['auth_password'])
REST_CLIENT = GerritRestAPI(url=MISC['base_url'], auth=REST_AUTH)
query = "/changes/" + str(change_id) + "/revisions/" + str(cur_rev) + "/review"
REST_CLIENT.post(query, json={
"message": MISC['message'],
"reviewers": [{
"reviewer": MISC['reviewer_bot']
}]
})
# MISC is a dictionary
You should be authenticated, shouldn't you? Therefore your requests would have to go to /a/changes/