POST body sent as separate request HttpConnection Python - python

I have the following code where a POST request is sent to a http server with a JSON request body. The debug prints out 2 requests, showing that the request body is sent as a separate request.
import http.client
import json
if __name__ == "__main__":
connexion = http.client.HTTPConnection('localhost',27015)
headers = {'Content-type': 'application/json','Accept': 'application/json'}
dataSent = {'coup': 'e2e4'}
json_dataSent = json.dumps(dataSent)
connexion.set_debuglevel(1)
connexion.request('POST','/faireCoup',json_dataSent,headers)
reponse = connexion.getresponse()
print(reponse.read().decode())
connexion.close()

Related

How to send data from python client to Django web server?

I'd like python3 program to send JSON data to Django web server and print them on web page. This is what I have in Views.py:
def receive_json(request):
if request.method == 'POST':
received_data = json.loads(request.body.decode("utf-8"))
return StreamingHttpResponse('it was post request: ' + str(received_data))
return StreamingHttpResponse('it was get request')
And the python code:
import requests
import json
url = "http://127.0.0.1:8000/"
data = {"data": [{'key1':'val1'}, {'key2':'val2'}]}
headers = {'content-type':'application/json'}
r = requests.post(url, data=json.dumps(data), headers=headers)
r.text
However, it shows this message:
Forbidden (CSRF cookie not set.): /
[28/May/2021 16:51:31] "POST / HTTP/1.1" 403 2864
import requests
import json
url = "http://127.0.0.1:8000/"
data = {"data": [{'key1':'val1'}, {'key2':'val2'}]}
headers = {'content-type':'application/json','Cookie':'csrftoken=axXsa39e5hq8gqlTjJFHAbUWtg2FQgnSd3cxxkx9khatqgersthtSryDxtF0cVCk'}
r = requests.post(url, data=json.dumps(data), headers=headers)
r.text
i think these may works by adding Cookie but it would be better if u use #csrf_exempt decorater in receive_json function by these way
from django.views.decorators.csrf import csrf_exempt
#csrf_exempt
def receive_json(request):
if request.method == 'POST':
received_data = json.loads(request.body.decode("utf-8"))
return StreamingHttpResponse('it was post request: ' + str(received_data))
return StreamingHttpResponse('it was get request')
Essentially you need first to perform a GET request to get a csrftoken, than post that together with the data. There are a few ways to do this. Here is one (untested however):
import requests
import json
url = "http://127.0.0.1:8000/"
s = requests.Session()
s.get(url)
headers = {
'content-type':'application/json',
'X-CSRFToken': s.cookies["csrftoken"],
}
data = {"data": [{'key1':'val1'}, {'key2':'val2'}]}
r = s.post(url, data=json.dumps(data), headers=headers)
r.text
You can find more information in Django's CSRF documentation.

Send simple message to Google Hangouts Chat bot using webhook

I've set up a webhook in a chat room in my Google Hangouts Chat.
I can successfully run their example code, which generates a message from the bot associated with the webhook in the chat:
from httplib2 import Http
from json import dumps
#
# Hangouts Chat incoming webhook quickstart
#
def main():
url = '<INCOMING-WEBHOOK-URL>'
bot_message = {
'text' : 'Hello from Python script!'}
message_headers = { 'Content-Type': 'application/json; charset=UTF-8'}
http_obj = Http()
response = http_obj.request(
uri=url,
method='POST',
headers=message_headers,
body=dumps(bot_message),
)
print(response)
if __name__ == '__main__':
main()
However, I wish to send this message using standard library packages, such as urllib.
But when I use urllib and run the below code, I get an urllib.error.HTTPError: HTTP Error 400: Bad Request. Why am I getting this error?
import json
import urllib.parse
import urllib.request
def main():
# python 3.6
url = '<INCOMING-WEBHOOK-URL>'
bot_message = {'text': 'Hello from Python script!'}
message_headers = {'Content-Type': 'application/json; charset=UTF-8'}
url_encoded = urllib.parse.urlencode(bot_message)
byte_encoded = url_encoded.encode('utf-8')
req = urllib.request.Request(url=url, data=byte_encoded, headers=message_headers)
response = urllib.request.urlopen(req)
print(response.read())
if __name__ == '__main__':
main()
The difference is in the body format. In the first version, you dump into json, while in the second you urlencode it.
replace
url_encoded = urllib.parse.urlencode(bot_message)
byte_encoded = url_encoded.encode('utf-8')
with
byte_encoded = json.dumps(bot_message).encode('utf-8')

Python requests parameters not going through

I'm trying to make a post request to Quizlet following their OAuth flow from these instructions https://quizlet.com/api/2.0/docs/authorization-code-flow. I'm running into a problem where on Step 2, I have to make a post request with a token I generated from their server, but I'm not having success passing in the token to the url. I know it was generated correctly, but I'm having trouble passing it in and not getting a 400 response.
More directly, my question is, is there another way of including the grant_type and code parameters that I'm trying to pass in through the url in the post request such as passing them in through the header of the post request? I've looked at the documentation for requests but I've had no luck.
#app.route('/')
#app.route('/index')
def index():
code = request.args.get('code')
state = request.args.get('state')
print("code is " + code)
r = requests.post("https://api.quizlet.com/oauth/token?grant_type=authorization_code&code=" + code)
return render_template('index.html')
You must specify the required headers Authorization, Content-Type.
import requests
from requests.auth import _basic_auth_str
client_id = 'YOUR CLIENT ID'
secret = 'YOUR CLIENT SECRET'
code = 'CODE FROM STEP 1'
headers = {
'Authorization': _basic_auth_str(client_id, secret),
'Content-Type': 'application/x-www-form-urlencoded'
}
r = requests.post('https://api.quizlet.com/oauth/token?grant_type=authorization_code&code={0}'.format(
code), headers=headers)
print r.status_code
print r.content

Issue with making transaction in Neo4J Python

I am trying to send a POST request with a Neo4j transaction query. Although I get a response 200 the node is not created. This is my Python script:
import requests
import json
import csv
headers = {'content-type': 'application/json'}
url = "http://localhost:7474/db/data/transaction/commit"
checkNode = {"query" : '{"statements": [{"statement":"CREATE (n:test) RETURN n"}]}'}
mkr =requests.post(url, data=json.dumps(checkNode), headers=headers)
print(mkr)
I haven't used transactions before and nver tried to create one through the Rest Api. What am I doing wrong here?
It seems unlikely to me that you're receiving a response code of 200; you should be getting a 500 as the transactional endpoint doesn't accept a query parameter. Try this:
import requests
import json
import csv
headers = {'content-type': 'application/json'}
url = "http://localhost:7474/db/data/transaction/commit"
checkNode = {"statements":[{"statement":"CREATE n RETURN n"}]}
mkr = requests.post(url, data=json.dumps(checkNode), headers=headers)
print(mkr.text)

Python requests Post request data with Django

I'm trying to send a simple post request to a very simple django server and can't wrap my head around why the post data isn't appearing in the requests post dictionary and instead its in the request body.
Client code:
payload = {'test':'test'}
headers = {'Content-type': 'application/json','Accept': 'text/plain'}
url = "localhost:8000"
print json.dumps(payload)
r = requests.post(url,data=json.dumps(payload),headers=headers)
Server Code:
def submit_test(request):
if request.method == 'POST':
print 'Post: "%s"' % request.POST
print 'Body: "%s"' % request.body
return HttpResponse('')
What is printed out on the server is:
Post: "<QueryDict: {}>"
Body: "{"test": "test"}"
I've played around with the headers and sending the data as a straight dictionary and nothing seems to work.
Any ideas? Thanks!!
The POST dictionary only contains the form-encoded data that was sent in the body of the request. The body attribute contains the raw body of the request as a string. Since you are sending json-encoded data it only shows up in the raw body attribute and not in POST.
Check out more info in the docs.
Try form-encoded data and you should see the values in the POST dict as well:
payload = {'test':'test'}
url = "localhost:8000"
requests.post(url, data=payload)
Specifying a user-agent in the headers should enable Django to interpret the raw data of the body and to correctly populate the POST dictionary. The following should work:
payload = {'test': 'test'}
url = "http://localhost:8000"
headers = {'User-Agent': 'Mozilla/5.0'}
requests.post(url, data=payload, headers=headers)
You should remove 'Content-type' from headers and use default one which is 'multipart/form-data'
response = client.post(
'/some_url/',
data={'post_key': 'some_value'},
# content_type='application/json'
)
If you uncomment 'content_type' data will be only in request.body

Categories

Resources