POST method of Powerbi api failing but GET is working (Python) - python

I'm trying to refresh a dataflow using python. It is working for me in Powershell. I'm not sure if I'm using Python correctly. Using Python, I'm able to do get method working correctly.
Python (get method :-> working)
import requests
groupID = <groupid>
#url = 'https://api.powerbi.com/v1.0/myorg/capacities'
header = {'Authorization': f'Bearer {access_token}','Content-Type':'application/json'}
datasets_request_url = 'https://api.powerbi.com/v1.0/myorg/groups/' + groupID + '/datasets'
response = requests.get(url=datasets_request_url, headers=header)
Python failing (POST Method)
dataflowid = <dataflowid>
dataflowrefresh_url = 'https://api.powerbi.com/v1.0/myorg/groups/' + groupID + '/dataflows/'+dataflowid+'/refreshes'
response = requests.post(url=dataflowrefresh_url, headers=header)
HTTPError: 400 Client Error: Bad Request for url:
PowerShell (POST method working)
$workspaceid = <groupid>
$dataflowid = <dataflowid>
$uri = "https://api.powerbi.com/v1.0/myorg/groups/$workspaceid/Dataflows/$dataflowid/refreshes"
# Build JSON, convert back and forth as we're just defining it as a string.
$json = '{"notifyOption": "MailOnFailure"}' | ConvertFrom-Json
$body = $json | ConvertTo-Json
# Refresh the dataflow
Invoke-RestMethod -Uri $uri -Headers $authHeader -body $body -Method POST -Verbose
If I remove the parameter $body, it fails with error 400. I don't know how to convert the working Powershell api call to Python.
Used the same token generated by below code. POST method worked in Powershell but not in Python, GET worked in both.
context = adal.AuthenticationContext(authority=authority_url,
validate_authority=True,
api_version=None)
token = context.acquire_token_with_client_credentials(resource_url, client_id, client_secret)
access_token = token.get('accessToken')

url = 'https://api.powerbi.com/v1.0/myorg/groups/' + workspaceID + '/dataflows/' +dataflowid+ '/refreshes'
payload= {'refreshRequest': 'y'}
data = json.dumps(payload)
headers = header
response = requests.request("POST", url, headers=headers, data=data)
Using refreshRequest : 'Y' made it work. In powershell, I didn't have to give this parameter.

Related

How to trigger pipeline API in AzureDevOps from Python (urllib3)

I have to trigger a pipeline in Azure DevOps from a python script. I have already found out that i need a private access token and that part is fine. I can, however, not get the script to work. I am trying something like this:
data = [
{
}
]
http = urllib3.PoolManager()
r = http.request('POST', api_url, headers={'Content-Type': 'application/json-patch+json', "Authorization": private_access_token}, body=data)
print(r.status)
print(r.data)
Its a requirement that i have to use urllib3 because I cant use the requests package
data is empty, because looking at the parameters here https://learn.microsoft.com/en-us/rest/api/azure/devops/pipelines/runs/run%20pipeline?view=azure-devops-rest-6.0. Then i dont need any input data? I just want to trigger a pipeline, nothing else
Error message is not very helpful. I get error message 203.
I solved it by using:
authorization = str(base64.b64encode(bytes(':'+private_access_token, 'ascii')), 'ascii')
data = {}
a = json.dumps(data)
http = urllib3.PoolManager()
r = http.request('POST', api_url, headers = {'Content-Type': 'application/json', 'Authorization': 'Basic '+authorization}, body=a)

What is the best method to return smmry api request with block of text in json instead of url?

I am trying to write a function in python that returns the json from a request to the smmry API. I was able to get it working with the SM_URL request like this:
def summry():
API_ENDPOINT = "https://api.smmry.com"
API_KEY = "B..."
params = {
"SM_API_KEY":API_KEY,
"SM_URL":"https:..."
}
r = requests.get(url=API_ENDPOINT, params=params)
return r.json()
However, I am not sure how you would do this for passing in a block of text instead of a URL. I have tried making the request with sm_api_input=my_input but that returned an error of insufficient variables. I have also tried it with a POST request and got the same error.
If anyone is curious, this is how I solved the problem. Turns out I needed an Expect: 100-continue header and the sm_api_input is a separate post field instead of a get query.
def summry(text):
API_KEY = "B..."
API_ENDPOINT = "https://api.smmry.com"
data = {
"sm_api_input":text
}
params = {
"SM_API_KEY":API_KEY
}
header_params = {"Expect":"100-continue"}
r = requests.post(url=API_ENDPOINT, params=params, data=data, headers=header_params)
return r.json()

Problems with POST to Quire API

I have been playing with Quire API using python and while the GET calls work fine, I can't do any successful POST calls. I get 400 error: Bad Request. I would appreciate any hints on what I might be doing wrong.
Below are relevant code snippets:
AUTH_ENDPOINT = 'https://quire.io/oauth/token'
API_ENDPOINT = 'https://quire.io/api'
data = {
'grant_type' : 'refresh_token',
'refresh_token' : 'my_refresh_code',
'client_id' : 'my_client_id',
'client_secret' : 'my_client_secret'
}
r = requests.post(url=AUTH_ENDPOINT, data=data)
response = json.loads(r.text)
access_token = response['access_token']
headers = {'Authorization' : 'Bearer {token}'.format(token=access_token)}
# This works fine
r = requests.get(url=API_ENDPOINT + '/user/id/me', headers=headers)
user = json.loads(r.text)
print(user)
# This doesn't work
task_oid = 'my_task_oid'
data = {
'description' : 'Test Comment'
}
r = requests.post(
url=API_ENDPOINT + '/comment/' + task_oid,
data=data,
headers=headers,
)
I am not familiar with the python requests API, so I don't know about default headers.
However it looks like you missed to send the request data as a JSON string:
here what worked for me from java script:
uri: '/comment/my_task_oid',
method: 'POST',
body: '{"description":"hello comment"}'
maybe it helps, in python as well.
also a curl example:
curl -X POST -H 'Authorization: Bearer my_access_token' -d "{\"description\" : \"a test comment\"}" https://quire.io/api/comment/my_task_oid
The answer provided by #cor3000 hinted that post data should be passed as JSON. I tested it out and indeed it works. Here is required modification to the POST reqest:
r = requests.post(
url=API_ENDPOINT + '/comment/' + task_oid,
data=json.dumps(data),
headers=headers,
)
Alternatively you can also do:
r = requests.post(
url=API_ENDPOINT + '/comment/' + task_oid,
json=data,
headers=headers,
)
More details in requests documentation: https://requests.kennethreitz.org/en/master/user/quickstart/#more-complicated-post-requests

Keep getting a 401 error when trying to pull data

I'm fairly new to using web APIs and pulling data and i'm also pretty new with python. My goal is to make a stat-tracker app but I keep getting a 401 when I try and pull the data.
I've printed out the entire url just to make sure I didn't get it wrong. I copied and pasted the API key exactly so that shouldn't be a problem
api_token = 'api key in python file'
api_url_base = 'https://public-api.tracker.gg/v2/apex/standard/'
headers = {'Content-Type' : 'application/json',
'Authorization' : 'Bearer {}'.format(api_token)}
def get_player_profile():
api_url = '{}profile/psn/Daltoosh'.format(api_url_base)
response = requests.get(api_url, headers=headers)
if response.status_code == 200:
return json.loads(response.content.decode('utf-8'))
else:
return response.status_code, api_url
print(get_player_profile())
#player_profile = get_player_profile()
#if player_profile is not None:
# print("Career Stats:")
# for k, v in player_profile['profile/psn/Daltoosh'].items():
# print('{0}:{1}.format(k, v)')
#else:
# print('[!] Data Request Failed [!]')
I expected a status code of 200 but there seems to be a problem authenticating.
I'm not too well versed in the web API that you are using, but I think you might be using the API token incorrectly. I don't think that specific API requires a Bearer token, but instead a separate header called TRN-Api-Key.
So maybe write something like this:
headers = {'Content-Type' : 'application/json', 'TRN-Api-Key' : api_token}
If you look here, you should be able to read up on how to set up authentication.

Spotify API authentication with Python

I'm trying to authenticate a user in the Spotify API, but it keeps returning me the error code "invalid_client". I'm implementing that on a Python Django solution, that's my code:
headers = {'Authorization': 'Basic '+standard_b64encode(client_id)+standard_b64encode(client_secret)}
r = requests.post('https://accounts.spotify.com/api/token', {'code': code, 'redirect_uri': redirect_uri, 'grant_type': grant_type, 'headers': headers}).json()
Any idea why it's not working?
In spotify api docs it is:
Authorization
Required. 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)
So i guess you should do:
import base64
'Authorization' : 'Basic ' + base64.standard_b64encode(client_id + ':' + client_secret)
It's working for me so try it. If it doesn't work my code is:
#staticmethod
def loginCallback(request_handler, code):
url = 'https://accounts.spotify.com/api/token'
authorization = base64.standard_b64encode(Spotify.client_id + ':' + Spotify.client_secret)
headers = {
'Authorization' : 'Basic ' + authorization
}
data = {
'grant_type' : 'authorization_code',
'code' : code,
'redirect_uri' : Spotify.redirect_uri
}
data_encoded = urllib.urlencode(data)
req = urllib2.Request(url, data_encoded, headers)
try:
response = urllib2.urlopen(req, timeout=30).read()
response_dict = json.loads(response)
Spotify.saveLoginCallback(request_handler, response_dict)
return
except urllib2.HTTPError as e:
return e
Hope it helps!
Are you sure you're providing client_id & client_secret in the proper format?
Looking at the docs, it suppose to be separated with :.
Also try to run the same flow with curl first and then replicate with python.

Categories