Problems with POST to Quire API - python

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

Related

{'error': 'RESTEASY003650: No resource method found for PUT, return 405 with Allow header'} when updating user data in Keycloak

I am trying to update user info in keycloak by sending put request. Get request is working fine I am getting all the users but Whenever I tried to send put request to update the user data I get this error "{'error': 'RESTEASY003650: No resource method found for PUT, return 405 with Allow header'}" while searching for the solution I find somewhere that I should add 'HTTP_X_HTTP_METHOD_OVERRIDE' in headers I also tried this but still, I am facing same error, how can I fix it.
code:
def update_user(user_id, user_data):
import requests
headers = dict()
headers['HTTP_X_HTTP_METHOD_OVERRIDE'] = 'PUT'
headers['content_type'] = 'application/json'
data = {
"grant_type": "password",
"username": "admin",
"password": os.getenv("KEYCLOAK_ADMIN_KEY"),
"client_id": "admin-cli"
}
token = _request("POST", f"{server_internal_url}realms/master/protocol/openid-connect/token", None, data=data).json()["access_token"]
# token = admin_token()
headers["Authorization"] = f"Bearer {token}"
headers["Host"] = kc_host
# here = _request("PUT", admin_url+f"/users"+"/".format(user_id=user_id), token, data=json.dumps(user_data)).json()
response = requests.put(admin_url+f"/users"+"/".format(user_id=user_id), headers=headers, data=data, verify=VERIFY)
print(response.json())
server_internal_url = "https://keycloak:8443/auth/"
admin_url = "https://keycloak:8443/auth/admin/realms/{realm_name}"
It looks like you request has wrong URL:
response = requests.put(admin_url+f"/users"+"/".format(user_id=user_id), headers=headers, data=data, verify=VERIFY)
I guess it should be:
response = requests.put(admin_url+"/users/"+user_id, headers=headers, data=data, verify=VERIFY)

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)

POST method of Powerbi api failing but GET is working (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.

Can't post file using python requests - Translation from curl

The following command works, but I can't reproduce it using python-requests (2.18.4) :
curl -X POST -H "Authorization: Bearer ..." \
-H "Content-Type: multipart/form-data" \
-F 'metadata={...}
-F 'data=#data.bz2;type=application/octet-stream'
https://www....com
Using the send_devices below, I receive "Unsupported Media Type""
def send_devices(basic_auth):
endpoint_api = ' https://www....com'
with open('data.bz2','rb') as payload:
response = requests.post(endpoint_api, data={'metadata': ...,
'data': payload},
headers={'Authorization': 'Bearer {0}'.format(basic_auth})
After some comments, I also tried and the error now is "Invalid Metadata Json String":
def send_devices(basic_auth):
endpoint_api = ' https://www....com'
files = {'file': ('data.bz2', open('data.bz2', 'rb'), 'application/octet-stream')}
response = requests.post(endpoint_api, data={"metadata": {"extensions":{"urnType":"IDFA"}}},
files=files, headers={'Authorization': 'Bearer {0}'.format(basic_auth)})
In the first example, was missing the file type
'data': ('data.bz2', open('data.bz2', 'rb'), 'application/octet-stream'),
In the second example, is necessary to add extra post data on the same files dict. Even if is not a dict:
'metadata': ('metadata.csv', json.dumps({"extensions": ...}))}
The solution:
def send_devices(basic_auth):
endpoint_api = ' https://www....com'
files = {'data': ('data.bz2', open('data.bz2', 'rb'), 'application/octet-stream'),
'metadata': ('metadata.csv', json.dumps({"extensions": ...}))}
response = requests.post(endpoint_api, files=files,
headers={'Authorization': 'Bearer {0}'.format(basic_auth)})
Make sure the payload is formatted correctly. It appears you are missing an '{' in your second object within your payload.
The HTTP 415 Unsupported Media Type client error response code indicates that the server refuses to accept the request because the payload format is in an unsupported format.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/415
You should put it as file (not as data).
r = requests.post(url, files={'file': open('data.bz2', 'rb')})
works fine.

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