How to make a connection to Parse via requests instead of httplib - python

I'm trying to connect to a custom endpoint I've set up on Parse Cloud Code. In the docs they show how to make a connection:
import json,httplib
connection = httplib.HTTPSConnection('api.parse.com', 443)
connection.connect()
connection.request('POST', '/1/functions/userData', json.dumps({
"userID": "1234"
}), {
"X-Parse-Application-Id": "####",
"X-Parse-REST-API-Key": "####",
"Content-Type": "application/json"
})
result = json.loads(connection.getresponse().read())
print result
This work great.
I'm trying to write it with requests but I continually get a 404:
import json, requests
PARSE_HOSTNAME = 'https://api.parse.com:443'
PARSE_APP_ID = '####'
PARSE_REST_API_KEY = '####'
endpoint = '/1/function/userData/'
headers = {"X-Parse-Application-Id": PARSE_APP_ID,
"X-Parse-REST-API-Key": "PARSE_REST_API_KEY",
"Content-Type": "application/json"}
payload = {'userID': '1234'}
r = requests.post(PARSE_HOSTNAME + endpoint, data=json.dumps(payload), headers=headers)
print r.json
Which prints out:
<bound method Response.json of <Response [404]>>
I feel like I'm missing something really obvious. Sorry for the ignorance.
How do I accomplish the same result as the first but with requests?

URL misspelling in the second example. You have
/1/function/userData/
must be
/1/functions/userData

Related

logging into the MATCHBOOK API with Python Requests

I am trying (legitimately and with the go ahead from the site)to log into the betting exchange matchbook.com through their api.
The documentation states:
To Login: https://www.matchbook.com/bpapi/rest/security/session
and
Example Request
POST /security/session
{
"username": "j_henry",
"password": "******"
}
Example Response
{
"session-token": "1418_1234567890",
"user-id": 1418,
"account": { // Same as GET /account API response.
...
}
}
I am using Requests and have the following code:
payload = {"username": "********", "password": "************"}
r = requests.post('https://www.matchbook.com/edge/rest/security/session', data=payload)
print (r.status_code)
I get error code 415? I must be getting the wrong type of response??
I have looked at a lot of very similar posts on here, and I am about to ask matchbook's team, but before I do has anybody got any ideas?
You might have to specify Content-Type, try to add a header to tell the server it's JSON formatted:
payload = {"username": "********", "password": "************"}
headers = {"Content-Type": "application/json;"}
r = requests.post('https://www.matchbook.com/edge/rest/security/session', data=payload, headers=headers)
print (r.status_code)
It does not appear from your code that you are JSON-encoding your payload. The endpoint is likely expecting JSON.
Try this:
payload = '{"username": "********", "password": "************"}'

What is meant by Non Canonical Serialization?

I am sending an http request to a server, and it keeps throwing a 400 http error
with an error message of Non Canonical Serialization. I am trying to get my head around what this message means from what i've read up so far it sounds like it has something to do with my object keys not being sorted when I serialize it to JSON meaning the server doesn't get the same result each time I send the request I just wanted to know if this is along the right lines? Or is it something else totally?
Here is my code sending the request to the server:
def submit(mutation, pubkey, signature):
headers = {'content-type' : 'application/json'}
url = "http://192.168.99.100:8080/submit/"
data = {
"mutation": mutation,
"signatures": [
{
"pub_key": pubkey,
"signature": signature
}
]
}
response = urllib2.Request(url, headers = { "Content-Type": "application/json"}, data=json.dumps(data))
f = urllib2.urlopen(response)
print f

How can I make a Post Request on Python with urllib3?

I've been trying to make a request to an API, I have to pass the following body:
{
"description":"Tenaris",
"ticker":"TS.BA",
"industry":"Metalúrgica",
"currency":"ARS"
}
Altough the code seems to be right and it finished with "Process finished with exit code 0", it's not working well. I have no idea of what I'm missing but this is my code:
http = urllib3.PoolManager()
http.urlopen('POST', 'http://localhost:8080/assets', headers={'Content-Type':'application/json'},
data={
"description":"Tenaris",
"ticker":"TS.BA",
"industry":"Metalúrgica",
"currency":"ARS"
})
By the way, this the first day working with Python so excuse me if I'm not specific enough.
Since you're trying to pass in a JSON request, you'll need to encode the body as JSON and pass it in with the body field.
For your example, you want to do something like:
import json
encoded_body = json.dumps({
"description": "Tenaris",
"ticker": "TS.BA",
"industry": "Metalúrgica",
"currency": "ARS",
})
http = urllib3.PoolManager()
r = http.request('POST', 'http://localhost:8080/assets',
headers={'Content-Type': 'application/json'},
body=encoded_body)
print r.read() # Do something with the response?
Edit: My original answer was wrong. Updated it to encode the JSON. Also, related question: How do I pass raw POST data into urllib3?
I ran into this issue when making a call to Gitlab CI. Since the above did not work for me (gave me some kind of error about not being able to concatenate bytes to a string), and because the arguments I was attempting to pass were nested, I thought I would post what ended up working for me:
API_ENDPOINT = "https://gitlab.com/api/v4/projects/{}/pipeline".format(GITLAB_PROJECT_ID)
API_TOKEN = "SomeToken"
data = {
"ref": ref,
"variables": [
{
"key": "ENVIRONMENT",
"value": some_env
},
{ "key": "S3BUCKET",
"value": some_bucket
},
]
}
req_headers = {
'Content-Type': 'application/json',
'PRIVATE-TOKEN': API_TOKEN,
}
http = urllib3.PoolManager()
encoded_data = json.dumps(data).encode('utf-8')
r = http.request('POST', API_ENDPOINT,
headers=req_headers,
body=encoded_data)
resp_body = r.data.decode('utf-8')
resp_dict = json.loads(r.data.decode('utf-8'))
logger.info('Response Code: {}'.format(r.status))
logger.info('Response Body: {}'.format(resp_body))
if 'message' in resp_body:
logfile_msg = 'Failed Gitlab Response-- {} {message}'.format(r.status, **resp_dict)
I recently became interested in using urllib3, and came across this problem. If you read the urllib3 "User Guide" page, you will see this:
For POST and PUT requests, you need to manually encode query parameters in the URL
Your code should be adjusted to look like this:
import urllib3
from urllib.parse import urlencode
data = {"description":"Tenaris",
"ticker":"TS.BA",
"industry":"Metalúrgica",
"currency":"ARS"}
http = urllib3.PoolManager()
encoded_data = urlencode(data)
http.request('POST',
'http://localhost:8080/assets?'+encoded_data,
headers={'Content-Type':'application/json'})

how do I format a python script to run cloud code on Parse?

Parse's quickstart guide gives this Python code to get started using cloud code:
import json,httplib
connection = httplib.HTTPSConnection('api.parse.com', 443)
connection.connect()
connection.request('POST', '/1/functions/hello', json.dumps({
}), {
"X-Parse-Application-Id": "xxxxxxxxxxxx",
"X-Parse-REST-API-Key": "xxxxxxxxxxxxx",
"Content-Type": "application/json"
})
result = json.loads(connection.getresponse().read())
print result
This code gives me a syntax error when I run it now matter what I do to it. How do I change the quotes or formatting to get it to work?
This seems to resolve whatever syntax problem there was:
# -*- coding: utf-8 -*-
import json,httplib
connection = httplib.HTTPSConnection('api.parse.com', 443)
connection.connect()
headers = {'Content-type': 'application/json'}
jdump = {'X-Parse-Application-Id': 'xxxxxxxxxxxxxx', 'X-Parse-REST-API-Key': 'xxxxxxxxxxx', 'Content-Type': 'application/json'}
json_jdumps = json.dumps(jdump)
connection.request('POST', '/1/functions/hello', json_jdumps, headers)
result = json.loads(connection.getresponse().read())
print result

post request to change permissions for a file in google drive is failing

Im using python requests library to make google a drive api request to change permissions of a file, in this case the owner.
Here is what my code looks like
fileId = "123abcEfJl-mNooP45Kl6u" #fake file id
url = https://www.googleapis.com/drive/v2/files/%s/permissions' % fileId
payload = {"role":"owner", "type":"user", "value":"<some_user>#gmail.com"}
headers = {'Authorization': 'Bearer %s'%access_token, 'Content-Type':'application/json'}
permResponse = requests.post(url, data=payload, headers=headers)
print permResponse.text
When I run this, I get the following response:
{
"error": {
"errors": [
{
"domain": "global",
"reason": "parseError",
"message": "Parse Error"
}
],
"code": 400,
"message": "Parse Error"
}
}
I've been following the google docs api for this and have not been able to figure out what im doing incorrectly.
https://developers.google.com/drive/v2/reference/permissions/insert
Even their Try It! section is broken because there isn't an option to add the required 'value' field.
What am I doing incorrectly? Is anyone else running into these issues?
Thanks
I'm using the urllib.request module, and It works fine. This is my code:
key = "?key=" + MY_API_KEY
url_destino = ("https://www.googleapis.com/drive/v2/files/%s/permissions" % source_id)+ key
values = "{"role":"owner", "type":"user", "value":"<some_user>#gmail.com"}"
data = values.encode('utf-8')
request = urllib.request.Request(url_destino, data, method='POST')
request.add_header("Authorization", "Bearer " + token)
request.add_header("Content-Length", len(data))
request.add_header("Content-Type", "application/json")
print(request.header_items()) # for debugging purpouse
f = urllib.request.urlopen(request)
print(f.read())
I've thought to replace the urllib.request by Requests module (it's more clean to work with) in my little library but, now works.
Because I use Python 3 I can't use the google-api-python-client.

Categories