Python-requests and Meteor / MongoDB collectionapi update not working - python

I'm trying to use Python Requests to send data to a Meteor application. I'm using the meteor-collectionapi to expose my collection.
I can use CURL to update my collection, like so:
curl -H "X-Auth-Token: 3243EEREFADfdsafkjghk432hljsfDS3" -X PUT -d "{\"\$set\":{\"level\":\"32\"}}" http://localhost:3000/collectionapi/containers/WjyuFkRdmq78qyzR7`
I'd like to perform the same command in Python using Requests. Here's the code I've put together:
import requests
import json
url = 'http://localhost:3000/collectionapi/containers/WjyuFkRdmq78qyzR7'
headers = {'X-Auth-Token': '3243EEREFADfdsafkjghk432hljsfDS3'}
payload = {'\$set':{'level':'43'}}
r = requests.post(url, data=json.dumps(payload), headers=headers)
When I run this the $set doesn't get passed properly and the POST doesn't work correctly (it creates a new object in the collection instead of updating the existing object). I've tried escaping it a variety of ways but nothing seems to work properly. If I don't escape the $set I get:
payload = {'$set':{'level':'38'}}
{"error":"Error: key $set must not start with '$'"}

In your cURL command you're not doing a POST, you're doing a PUT.
Try changing your requests command to
r = requests.put(url, data=json.dumps(payload), headers=headers)

Related

How to handle special characters in python requests post request

I'm trying to send an HTTP POST request using the python requests package.
The working curl command looks like the following (captured from chrome dev tools network tab, right clicked on someFile.php, and chose "copy as cURL"). When run in a terminal, it outputs a valid, nonempty, response.
curl 'https://somedomain.com/someFile.php' \
--data-raw $'abc=ZXC%20*%20QWE%20***%20BNM%20((someThing%20%3D%200))%20AND%20anotherThing%20%3E%3D%20\'2020-5-9\'%20IOP%20&someparam=1&myhash=a5d96895cab824fbd9bb85627a8f909d'
I attempted to replicate the POST request in python with:
import requests
url = 'https://somedomain.com/someFile.php'
out = requests.post(url,data=r'abc=ZXC%20*%20QWE%20***%20BNM%20((someThing%20%3D%200))%20AND%20anotherThing%20%3E%3D%20\'2020-5-9\'%20IOP%20&someparam=1&myhash=a5d96895cab824fbd9bb85627a8f909d')
print(out.text)
... but this just prints an empty string.
How do I handle this curl command in python?
Simply setting Content-Type header to application/x-www-form-urlencoded should solve your problem.
headers={}
headers["Content-Type"]="application/x-www-form-urlencoded"
data="....."
output=requests.post(url,headers=headers,data=data)
url="https://somedomain.com/someFile.php"
params = {"abc":"text without quote symbols", "someParam":.... }
res=requests.post(url, params=params)
print(res.text)

Curl works but python requests doesn't

When I do curl, I get a response:
root#3d7044bac92f:/home/app/tmp# curl -H "Content-type: application/json" -X GET https://github.com/timeline.json -k
{"message":"Hello there, wayfaring stranger. If you\u2019re reading this then you probably didn\u2019t see our blog post a couple of years back announcing that this API would go away: http://git.io/17AROg Fear not, you should be able to get what you need from the shiny new Events API instead.","documentation_url":"https://developer.github.com/v3/activity/events/#list-public-events"}
However, when I do python requests to the same URL I get a status 410.
import requests
headers = {
'Content-type': 'application/json',
}
r = requests.get('https://github.com/timeline.json')
print r.json
root#3d7044bac92f:/home/app/tmp# python rest.py
<bound method Response.json of <Response [410]>>
What gives?
The host is a standard Ubuntu docker image and only installed Curl and some python modules. Python -V is 2.7
Note: I looked at this question but I can't telnet into above server so that solution doesn't apply to me:
Curl works but not Python requests
You've made at least two errors in your program.
1) You haven't specified the data= or headers parameters to the requests.get() call. Try this:
r = requests.get('https://github.com/timeline.json', data=data, headers=headers)
2) .json is a method, not a data attribute of the response object. As a method, it must be called in order to be effective. Try this:
print r.json()

API response with a proxy is working with the curl, but nothing is returned with python

I am trying to access data using API which is behind the proxy server. If I use curl command like below it works:
curl --proxy http://MY_PROXY_SERVER:PORT --header "Accept: application/csv" http://WEB_SERVER_ADDRESS/data/CHANNEL?start=1470011400
I get the data which is expected.
When I am trying to access the same URL with python either by requests or urllib2 I am not able to get the data back. This is the code:
from __future__ import print_function
import requests
s = requests.Session()
s.proxies = {"http": "http://MY_PROXY_SERVER:PORT"}
headers = {'Accept': 'application/csv'}
url = "http://WEB_SERVER_ADDRESS/data/CHANNEL?start=1470011400"
r = s.get(url, headers=headers)
print(r.text)
I don't get any error and request is able to go through the python successfully. The output is empty list. I also tried with other media type supported by API like 'json', issue still persists.

Executing URLs in Python similar to curl in Linux - JenkinsAPI

I am trying to trigger some builds using a shell script by doing the following :
export url='http://test.com';
export job_name='MY_JOB_NAME';
jso="{\"parameter\": [{\"name\":\"BRANCH\",\"value\":\"master\"}, {\"name\":\"GITURL\",\"value\":\"https://github.test.com/test/test.git\"}]}";
curl $url/job/$job_name/build --data-urlencode json="$jso";
This works fine, but when I try to convert it to a python equivalent, it doesn't seem to trigger the URL:
import requests
import json
url='http://test.com/job/MY_JOB_NAME/build'
params={'name':'release_1.5', 'GITURL':'https://github.test.com/test/test.git'}
payload = json.dumps(params)
resp = requests.get(url=url, data=payload)
This executes without any error, but it does not trigger a build on my CI machine.
There are quite a few things you're doing wrong here. The first thing which I hope is apparent is that the JSON data you're sending is completely different.
Beyond that, the primary issue you're having here is that your curl is doing a POST with urlencoded data in the BODY, and your python request is doing a GET with urlencoded data as separate parameters in the url. Change your .get to a .post, and the params= to data= and you should be a whole lot closer to your intended goal.
resp = requests.post(url=url, data={'json':payload})
Also note, I embedded your payload into a key as json, as that's what is happening in your curl. I'm not fully aware of your implementation details, but I hope that this helped put you on the right track.
Add the content-type to the header of the request, i.e.:
headers = {'content-type': 'application/json'}
...
resp = requests.get(url=url, params=payload, headers=headers)

sending data parameters to rest api using python-requests

I am trying to call rest api by sending json data. The curl command is pretty straight forward but only problem that I am facing is with "--data" parameter.
For curl, the data is sent as follows:
curl -X POST -H <headers> --data 'params={...}' <url>
I am not able to figure out how to send the --data parameter with the name 'params='attached to it using python-requests.
Also while making GET requests, there are a lot of options which I have to send along with the curl requests(-O ,-J, -v, -G,-L).
I wanted to know how to supply these additional parameters using python-requests.
Thanks.
curl is a very rich library that has gone far way after a lot of developments in last decades. Compare to the curl, python's requests library is still a baby. So you can not expect all the functionalities of curl in requests. You'll only get the major functionalities of curl in your requests.
Now come to your question. If you want to send the json data through a variable, then the basic POST operation(content-type application/x-www-form-urlencoded) will do.
payload = {'params': json_string}
r = requests.post("http://url/post", data=payload)
But if you want to POST the data as json object with header content-type as json, then you have to use this
headers = {'content-type': 'application/json'}
r = requests.post(url, data=json_string, headers=headers)
In Curl the param -L means for following the redirection. You can achieve it with allow_redirects=True parameter:
r = requests.post(url, data=json_string, headers=headers, allow_redirects=True)
Help yourself to find your needs from the requests document.

Categories

Resources