Python Django ConnectionAbortedError [WinError 10053] - python

So im facing a weird issue while making a request to my api. It works fine using something like postman. I get my response no issue but if I make a request from my frontend(on a seperate domain) the connection gets closed for some reason.
Here is my code
I make ajax request using axios
axios.get(mydomain/api/oauth)
.then(response => {
console.log(response)
}).catch(error => {
console.log(error.response.data)
})
which hits my backend method that should return a response like so
def oauth(request):
auth_client = AuthClient(
settings.CLIENT_ID,
settings.CLIENT_SECRET,
settings.REDIRECT_URI,
settings.ENVIRONMENT
)
url = auth_client.get_authorization_url([Scopes.ACCOUNTING])
request.session['state'] = auth_client.state_token
return HttpResponse(url)
But at this point I get this alarm
ConnectionAbortedError: [WinError 10053] An established connection was aborted by the software in your host machine
And like I said if I make this same request through postman I get my response. So I don't know what I am missing. I have applied cors thinking maybe its because my frontend is on seperate domain from backend but no luck. Plus the alarm is kind of vague... anybody face similar issue?

Related

GET request via python script with access token

I'm facing some difficulties executing GET request with access token via python.
For some reason when I execute the request from POSTMAN I get the expected result, however, when using python I get connection error :
A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
I believe that my script is being blocked by the server to prevent scrapping attempts, but I'm not sure.
This is what I'm running via POSTMAN :
https://www.operation.io/web/alerts?access_token=6ef06fee265de1fa640b6a444ba47--z&envId=58739be2c25e76a202c9dd3e&folderId=active&sortBy=status
And this is what I'm running from inside the script :
response = requests.get('https://www.operation.io/web/alerts', headers={'Authorization': 'access_token 6ef06fee265de1fa640b6a444ba47--z'})
Please notice that the url and the access token are not real, so please don't try to use.
How can I make it work via the script and not only via postman?
Thank you for your help/
It's hard to tell without actually being able to test the solutions, but I would suggest 2 hacks that worked for me in the past:
Change "Authorization" to "authorization"
Change "6ef06fee265de1fa640b6a444ba47--z" to "Token 6ef06fee265de1fa640b6a444ba47--z" (add a space as well)
Put it all together:
response = requests.get('https://www.operation.io/web/alerts', headers={'authorization': 'Token 6ef06fee265de1fa640b6a444ba47--z'})
Since via postman you're sending the token as query param(as opposed to header), you can try this :
response = requests.get('https://www.operation.io/web/alerts', params={'access_token': '6ef06fee265de1fa640b6a444ba47--z'})
Assuming the API you're using accepts it as query param rather than as headers (which is my guess from the postman request)

In Django, how to re-package a Request.response as a Django response?

I have a Django App that accepts messages from a remote device as a POST message.
This fits well with Django's framework! I used the generic View class (from django.views import View) and defined my own POST function.
But the remote device requires a special reply that I cannot generate in Django (yet). So, I use the Requests library to re-create the POST message and send it up to the manufacturer's cloud server.
That server processes the data, and responds with the special message in the body. Idealy, the entire HTML response message should go back to the remote device. If it does not get a valid reply, it will re-send the message. Which would be annoying!
I've been googling, but am having trouble getting a clear picture on how to either:
(a): Reply back in Django with the Requests.response object without any edits.
(b): Build a Django response and send it back.
Actually, I think I do know how to do (b), but its work. I would rather do (a) if its possible.
Thanks in Advance!
Rich.
Thanks for the comments and questions!
The perils of late night programming: you might over-think something, or miss the obvious. I was so focused on finding a way to return the request.response without any changes/edits I did not even sketch out what option (b) would be.
Well, it turns out its pretty simple:
s = Session()
# Populate POST to cloud with data from remote device request:
req = Request('POST', url, data=data, headers=headers)
prepped = req.prepare()
timeout = 10
retries = 3
while retries > 0:
try:
logger.debug("POST data to remote host")
resp = s.send(prepped, timeout=timeout)
break
except:
logger.debug("remote host connection failed, retry")
retries -= 1
logger.debug("retries left: %d", retries)
time.sleep(.3)
if retries == 0:
pass # There isn't anything I can do if this fails repeatedly...
# Build reply to remote device:
r = HttpResponse(resp.content,
content_type = resp.headers['Content-Type'],
status = resp.status_code,
reason = resp.reason,
)
r['Server'] = resp.headers['Server']
r['Connection'] = resp.headers['Connection']
logger.debug("Returning Server response to remote device")
return r
The Session "s" allows one to use "prepped" and "send", which allows one to monkey with the request object before its sent, and to re-try the send. I think at least some of it can be removed in a refactor; making this process even simpler.
There are 3 HTTP object at play here:
"req" is the POST I send up to the cloud server to get back a special (encrypted) reply.
"resp" is the reply back from the cloud server. The body (.content) contains the special reply.
"r" is the Django HTTP response I need to send back to the remote device that started this ball rolling by POSTing data to my view.
Its pretty simple to populate the response with the data, and set headers to the values returned by the cloud server.
I know this works because the remote device does not POST the same data twice! If there was a mistake anyplace in this process, it would re-send the same data over and over. I copied the While/try loop from a Socket repeater module. I don't know if that is really applicable to HTTP. I have been testing this on live hardware for over 48 hours and so far it has never failed. Timeouts are a question mark too, in that I know the remote device and cloud server have strict limits. So if there is an error in my "repeater", re-trying may not work if the process takes too long. It might be better to just discard/give up on the current POST. And wait for the remote device to re-try. Sorry, refactoring out loud...

Parse Server error: unauthorized and Python connection issues

I just set up my first Parse test server on Heroku, and am having 2 main issues:
Issue 1) https:// [MY SERVER URL] /parse is returning {error: 'unauthorized'}. I've tried using Postman to authenticate using the headers
"X-Parse-Application-Id": xxx
"X-Parse-Master-Key": yyy
where xxx and yyy are my AppID and MasterKey.
Issue 2) I am not able to connect to the API using Python. I AM able to submit successful requests from the Parse dashboard itself, and also using cURL:
curl -X GET -H "X-Parse-Application-Id: xxx" -H "X-Parse-REST-API-Key: undefined" https://[MY SERVER URL]/parse/classes/Customer (this works)
But when I use the following code (as it states in the Parse API documentation), I am not getting getting an
ConnectionResetError: [Errno 54] Connection reset by peer
This doesn't surprise me, since here is the Python script I'm using to connect:
import json,http
connection = http.client.HTTPConnection('api.parse.com', 443)
connection.connect()
connection.request('GET',
'/1/classes/Customer/', '', {
"X-Parse-Application-Id": "myAppID",
"X-Parse-REST-API-Key": "undefined"
})
result = json.loads(connection.getresponse().read())
In particular, it's the connection.getresponse() function call that is returning the error.
I know this doesn't look right since I don't see where I'm supposed to specify my server URL, and I have a suspicion these two issues are interconnected. Can someone help me shed some light on what's going on? I've read through the PARSE REST documentation pretty thoroughly (https://parseplatform.github.io/docs/rest/guide/) and followed along using the same structure for the requests.

Problem with POST request from APE server module

I use Ajax Push Engine as push engine and Django for main site. I wrote the server
module which must send the request to my Django-based application when
new user join the channel by using Http module. My Django-based project runs on the local
machine on local.jjjbbb.org.
Ape.addEvent("join", function(user, channel) {
var request = new Http('http://local.jjjbbb.org/test-
this/'); // this is a my test url
request.set('method', 'POST');
request.writeData('test-message', 'Hello APE!');
request.getContent( function(result) {
Ape.log(result); // this code never work
});
});
But this code doesn't work, request doesn't receive. When I change url
to anything else (like www.google.com or localhost for example) all
works correctly and I have a result. But when I try to send request to
my application request doesn't work. This problem is only when I try
to send request from server side, when I use jQuery for sending from
client side all works correctly.
Why I cannot send POST request from server side to my domain?
Sorry, I already found my problem. APE works fine, it was a little trouble with CSRF protection in Django.

Problem with json response in Python REST server I'm writing

For my own education I'm creating a simple daemon that will function as a REST server, listening on socket 9000. For my first test I'm trying to do a REST call of simply doing a GET on http://localhost:9000/getsettings.json.
The simple server I hacked up gets the request OK, but I think there's a problem with the response it's sending. I'm trying to send the response as JSON. The code for the server socket is below. Below that is the jQuery code I'm using to make the JSON request. The print statement in the Python server does print a valid set of settings in JSON format. Neither alert in the Javascript is being called when the page loads. Any ideas?
Python:
def socketThread(self):
while 1:
sock, address = self.serverSocket.accept()
fs = sock.makefile()
line = fs.readline();
if line.startswith('GET /settings.json'):
sock.sendall("HTTP/1.0 200 OK\r\n")
sock.sendall("Content-Type: application/json\r\n")
settings = json.dumps(self.currentSettings) #, indent=4
sock.sendall("Content-Length: " + str(len(settings)) + '\r\n\r\n')
sock.sendall(settings)
print settings
sock.close()
Javascript:
$(document).ready(function() {
$.ajax({
url: 'http://localhost:8080/settings.json',
cache: false,
success: function(json){
alert('json success ' + json);
},
error: function(xhr, textStatus, errorThrown) {
alert(xhr.statusText);
}
});
});
You need to return a 200 OK HTTP response and an empty line before sending your content.
You'll probably need some HTTP headers, too (Content-type would be an obvious one).
I would, however, recommend using one of Python's many HTTP libraries instead of implementing the protocol yourself.
Check that the server is actually being hit (eg, put an import pdb; pdb.set_trace() in your code. I found that jQuery executes the success callback with empty body when the server is not running (or listening on a different port...)
OK, the problem was on the jQuery side, my request was being thwarted by the cross domain origin protection issue - my request was going to localhost on a different port so jQuery wasn't pulling down the data. Now I need to figure out how to make that work. Thanks for the help guys.

Categories

Resources