Calling RESTful API Using Python on Google App Engine - django

I got some problems when calling RESTful webservice.
I'm running a Django 1.5 project on google app engine now.
And I make use of httplib in python to call a RESTful webservice.
All methods(PUT, GET, DELETE, POST) work well on my local Machine (python 2.7.5, Django 1.5).
However, the behavior is changed on GAE...
PUT (used to store the data which user edited his information on the sites.), POST method is work well.
The GET method sometimes can't get the latest results from webservice server (not google datastore, the data are stored in other database server, I use the GET method to fetch the data from that server).
The DELETE method is not working totally on GAE.
Here is my code:
import httplib
args = ""
headers = {"Accept":"application/json"}
conn = httplib.HTTPConnection(IP, 8080)
try:
conn.request("DELETE", Some_API_Method_Url, args, headers)
response = conn.getresponse()
res = response.read()
I can't figure out why this happened, hoping someone can help me :(
Thanks in advance!
UPDATED:
I just found why the DELETE method is not working based on this link.
I send an ajax request which type is delete in my js file to my Django backend with the following code:
$.ajax({
type:'DELETE',
url:'some_url',
data:JSON.stringify({'key':'value'}),
contentType: 'application/json; charset=utf-8',
dataType: "text",
success: function(data){...},
error: function(data){...}
});
It seems that the appspot doesn't allow the DELETE request with body(data).
so, I changed the type of the AJAX request to POST, and it works...

Related

503 error when fetching an internal NextJS api with query parameters on AWS Amplify

I am trying to fetch data from a JSON file through NextJS internal API on the client side. But it is always throwing 503 error:
The Lambda function associated with the CloudFront distribution is invalid or doesn't have the required permissions.
We can't connect to the server for this app or website at this time. There might be too much traffic or a configuration error. Try again later, or contact the app or website owner.
I tried to use the GET method with query params in the URL, but it didn't work, then I try the POST method with the query in the body(just to test out), but it also didn't work either.
Here is the code:
const response = await fetch(`/api/search?q=${query}`, {
method: "GET",
headers: {
'Content-Type': 'application/json',
},
})
const res = await response.json()
I have another component that sends some user inputs to save in my DB, and it is working perfectly. (I am really confused why one works but not other given both are equivalent request)
Also, the same app deployed on Vercel is working perfectly. So I think the issue is with Amplify.
Anyone had similar issues with the Next app on Amplify? please help.
most likely you are sending a GET request but you have something in the body. e.g. form-data. this is example in postman.

Unity 2017.3 HTTP POST request always empty when it hits web app (Django)

I'm trying to use Unity 2017.3 to send a basic HTTP POST request from Unity scripting. I want to send an image data, which I can access in my script either as file.png or in a byte[]. I am only posting to a local server running Python/Django, and the server does register the POST request coming in - but no matter what I do the request arrives empty of any content, body, files or raw data at my web app.
IEnumerator WriteAndSendPng() {
#extra code that gets bytes from a render texture goes here
#can verify that drawing.png is a valid image for my purposes
System.IO.File.WriteAllBytes("drawing.png", bytes);
List<IMultipartFormSection> formData = new List<IMultipartFormSection>();
formData.Add( new MultipartFormFileSection ("drawing", bytes, "drawing.png", "image/png") );
UnityWebRequest www = UnityWebRequest.Post("http://127.0.0.1:8000/predict/", formData);
yield return www.SendWebRequest();
if(www.isNetworkError || www.isHttpError) Debug.Log(www.error);
else Debug.Log("Form upload complete!");
}
I'm following the docs and there are a bunch of constructors for MultipartFormFileSection, most of which I feel like I've tried. Also tried UploadHandlers, or the old AddBinaryField WWW API - still the request is always empty when it hits my app... I've read the thorough response to this SO ticket, Sending http requests in C# with Unity. I have tried many of the implementations here but again, Django receives empty requests. Even submitting the simplest possible request from Unity sends empty requests. So weird.
List<IMultipartFormSection> formData = new List<IMultipartFormSection>();
formData.Add (new MultipartFormDataSection ("someVar=something"));
The Python server just sees:
[11/Feb/2018 14:14:12] "POST /predict/ HTTP/1.1" 200 1
>>> print(request.method) # POST
>>> print(request.encoding) # None
>>> print(request.content_type) #multipart/form-data
>>> print(request.POST) # <QueryDict: {}>
>>> print(request.body) # b''
I thought it might be a Django issue, but posting to the same app w/ Postman or from other sources, it sees the incoming data just fine. Anyone done this recently? I thought this would be a piece of cake and many hours into into it I remain stymied. All help appreciated! Thanks, all.
Figured it out courtesy of Unity staffer Aurimas-Cernius on their forums: "The issue most likely is that your Django server does not support HTTP 1.1 chunked transfer. You can either try updating your server, or set chunkedTransfer property on UnityWebRequest to false."
He was right. Setting that flag to false allowed me to start sending simple test case data and receiving it as expected in the Django app - bet I'll be able to get images working in no time. I was also experiencing side effects of using Python 3.5.x (mistakenly assuming I needed to). Upgrading that fixed the chunk issue, too. Cheers!

Login using python request module on a aspx webpage

I've being trying to log in to this web page but I fail every time. This is the code i used
import requests
headers = {'User-Agent': 'Chrome'}
payload = {'_GlobalLoginControl$UserLogin':'myUser','_GlobalLoginControl$Password':'myPass'}
s = requests.Session()
r = s.post('https://www.scadalynx.com/GlobalLogin.aspx',headers=headers,data=payload)
r = s.get('https://www.scadalynx.com/Default.aspx')
print r.url
The result I get from: print r.url is this:
https://www.scadalynx.com/GlobalLogin.aspx?Timeout=Y
You can't.
The main problem is, your payload isn't complete. Check chrome's networking tab. There are much more required payloads.
ScriptMgr:_GlobalLoginControl$UpdatePanel1|_GlobalLoginControl$LoginBtn
ScriptMgr_HiddenField:;;AjaxControlToolkit, Version=4.1.40412.0, Culture=neutral, PublicKeyToken=28f01b0e84b6d53e:en-US:2d0688b9-5fe7-418f-aeb1-6ecaa4dca45f:475a4ef5:effe2a26:751cdd15:5546a2b:dfad98a5:1d3ed089:497ef277:a43b07eb:3cf12cf1
__EVENTTARGET:
__EVENTARGUMENT:
__VIEWSTATE:/wEPDwUKMTQxMjQ3NTE5MA9kFgICAQ8WAh4Ib25zdWJtaXQFkgFpZiAoJGdldCgnX0dsb2JhbExvZ2luQ29udHJvbF9QYXNzd29yZCcpICE9IG51bGwpICRnZXQoJ19HbG9iYWxMb2dpbkNvbnRyb2xfUGFzc3dvcmQnKS52YWx1ZSA9IGVzY2FwZSgkZ2V0KCdfR2xvYmFsTG9naW5Db250cm9sX1Bhc3N3b3JkJykudmFsdWUpOxYEAgEPZBYCZg9kFgICBQ9kFgICAg9kFgICAQ9kFgJmD2QWCgIND2QWAgIJDw9kFgIeB29uY2xpY2sFugFqYXZhc2NyaXB0OmlmKCRnZXQoJ19HbG9iYWxMb2dpbkNvbnRyb2xfX0ZvcmdvdFBhc3N3b3JkRU1haWxUZXh0Qm94JykgIT0gbnVsbCkkZ2V0KCdfR2xvYmFsTG9naW5Db250cm9sX19Gb3Jnb3RQYXNzd29yZEVNYWlsVGV4dEJveCcpLnZhbHVlID0gJGdldCgnX0dsb2JhbExvZ2luQ29udHJvbF9Vc2VyTG9naW4nKS52YWx1ZTtkAg8PZBYCAgUPEGRkFgBkAhEPD2QWAh8BBZUDamF2YXNjcmlwdDppZigkZ2V0KCdfR2xvYmFsTG9naW5Db250cm9sX1VzZXJMb2dpblZhbGlkYXRvcicpICE9IG51bGwpJGdldCgnX0dsb2JhbExvZ2luQ29udHJvbF9Vc2VyTG9naW5WYWxpZGF0b3InKS5lbmFibGVkID0gdHJ1ZTtpZigkZ2V0KCdfR2xvYmFsTG9naW5Db250cm9sX19Vc2VyTG9naW5SZWd1bGFyRXhwcmVzc2lvblZhbGlkYXRvcicpICE9IG51bGwpJGdldCgnX0dsb2JhbExvZ2luQ29udHJvbF9fVXNlckxvZ2luUmVndWxhckV4cHJlc3Npb25WYWxpZGF0b3InKS5lbmFibGVkID0gdHJ1ZTtpZigkZ2V0KCdfR2xvYmFsTG9naW5Db250cm9sX1Bhc3N3b3JkVmFsaWRhdG9yJykgIT0gbnVsbCkkZ2V0KCdfR2xvYmFsTG9naW5Db250cm9sX1Bhc3N3b3JkVmFsaWRhdG9yJykuZW5hYmxlZCA9IHRydWU7ZAITD2QWAgIBDw8WAh4HVmlzaWJsZWhkZAIVD2QWBAIBDw9kFgIfAQUtJGdldCgnX0dsb2JhbExvZ2luQ29udHJvbF9QYXNzd29yZCcpLmZvY3VzKCk7ZAILDw9kFgIfAQVhamF2YXNjcmlwdDokZ2V0KCdfR2xvYmFsTG9naW5Db250cm9sX19Gb3Jnb3RQYXNzd29yZEVNYWlsUmVxdWlyZWRGaWVsZFZhbGlkYXRvcicpLmVuYWJsZWQgPSB0cnVlO2QCAg8PFgIfAmhkFgICAw8WAh4LXyFJdGVtQ291bnRmZBgBBR5fX0NvbnRyb2xzUmVxdWlyZVBvc3RCYWNrS2V5X18WAwUpX0dsb2JhbExvZ2luQ29udHJvbCRSZW1lbWJlckxvZ2luQ2hlY2tCb3gFK19HbG9iYWxMb2dpbkNvbnRyb2wkX0ZvcmdvdFBhc3N3b3JkQ2xvc2VCdG4FEV9FcnJvckltYWdlQnV0dG9uIXu7XOl6z8WoghCWdElD7kNBanI=
__VIEWSTATEGENERATOR:ABDC7715
__SCROLLPOSITIONX:0
__SCROLLPOSITIONY:0
__EVENTVALIDATION:/wEdAA8j+x15hTpBOEjDv1LxVan3AUijrFjxy9PpisoGxfMqnNduSMVw1RChh3aZsdCK82jXRUWkWThaqEhU3Gr5iw98GHoUhEtg6gp73QcFIR1tGEGQHmQGQos+5LR8l78kIyNCGm6wvkKBlG3Z3EngFWzmX3gMRUNTCvY9T8lfFGMsRkvp3s0LtAU9sya5EgaP5MNrqxxx0HTfWwHJy49saUYlPDg6OL5q3VoZ6biOkvIG8l/ujxMESq+8VmX4sGwXcQBJxOm7RbAd1IEojVITrtk4hx8VhfPuqTNrqWHRrUAMgBj1ffXkwiR7kcJxJ3ixy43iLukJszI09WI7xsAFyAKxG82PcA==
_GlobalLoginControl$ScrWidth:1536
_GlobalLoginControl$ScrHeight:864
_GlobalLoginControl$UserLogin:asdsad#asdas.com
_GlobalLoginControl$Password:asdasd
_GlobalLoginControl$PasswordStore:
_GlobalLoginControl$HiddenField1:
_GlobalLoginControl$_HiddenSessionContentID:
_ErrorHiddenField:
__ASYNCPOST:true
_GlobalLoginControl$LoginBtn:Login
Probably, you could outsource this (I think it isn't possible, you have to use selenium or get the page first and scrape the informations.
But check this topic: How to make HTTP POST on website that uses asp.net?
We considered that, the login should be pass-through with phantomjs/chrome with selenium, the you should pass the cookies and the headers to requests. After you pass the required informations for requests, you could work with request for the further steps.

Ionic app not issuing POST request

I have an interesting problem with my Ionic application with a Django API server backend.
In previous versions of my app (0.0.1-.0.0.5) this hasn't come up, but starting now I'm not able to issue a POST request to get my authentication token.
Using Ionic locally ionic serve against my deployed server, when I attempt a login, my server registers an OPTIONS /token-auth/ and then POST /token-auth/. When I run the application on my device ionic run android and attempt to login the server only registers the OPTIONS request but does not register the POST, according to the server logs.
I've found out this is due to CORS, it issues an OPTIONS first to see what it is allowed to issue. For some reason the OPTIONS request comes back with absolutely nothing. In my other Django Rest Framework projects, the OPTIONS comes back with a proper response. I think this is related, but it's strange that it works from localhost to the deployed server with the OPTIONS request responding the same.
My login function is pretty basic:
$http({
method: 'POST',
url: config.apiUrl + 'token-auth/',
data: {
"username": usernameElement[0].value,
"password": passwordElement[0].value
}
}).then(function(data) {
console.log('success', data);
...
}, function(err) {
console.log('error', err);
...
});
Another thing I find interesting is that it runs the error function but instead of giving me back a normal error object in the err variable, I get back what appears to be the request object. I have never seen this before.
{
"data":null,
"status":0,
"config":{
"method":"POST","transformRequest":[null],
"transformResponse":[null],
"url":"http://example.com/api/token-auth/",
"data":{
"username":"myuser",
"password":"mypassword"
},
"headers":{
"Accept":"application/json, text/plain, */*",
"Content-Type":"application/json;charset=utf-8"}
},
"statusText":""
}
Runs fine local app to deployed server
Device app to deployed server doesn't register POST request, only OPTIONS
AJAX error return is the request object, not the error response object
I've been stuck on this for a couple days now and am looking for any ideas.
This was in fact a CORS problem. After debugging through django-cors-headers I found that it was not passing the CORS. I later found out that instead of serving on http://192.168.1.36:8100 for some reason ionic switched to serve on http://192.168.1.10:8100

EmberJs as a PhoneGap with external API

please can you advise on the following:
I have a web application written in emberjs with Rails as back-end. And now I'm going to port this application with phonegap to iOS, and the thing that I'm struggling is how to set my API endpoint that will be working in iPhone?
As I understand EmberJs when used on the web via browser, uses your current location to issue API requests, but this approach doesn't working when using the application as iOS app.
I'm really looking for some elegant solution to simply replace the host name or something?
Thanks for help!
UPDATE:
This one works for changing the API URL
DS.RESTAdapter.reopen({
url: 'http://somedomain.com'
});
But now, there is access-controll issue:
Origin http://somedomain.com is not allowed by Access-Control-Allow-Origin.
Since you haven't posted any code on how your adapter is configured, this is the right way to set a custom url for your adapter:
DS.RESTAdapter.reopen({
url: 'https://somedomain.com/api'
});
Then if you have a model e.g. App.User, the requests for the list of App.User would now go to https://somedomain.com/api/user/ and for a specific user id to https://somedomain.com/api/user/123 respectively.
Update
When testing from the browser you have to start the browser (assuming chrome) with the flag --disable-web-security to make cross origin work. But in real live you have to configure your server to set the response HTTP HEADERS using:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, ...
So in the case of rails you could do something like this to configure your controllers serverside to accept cross origin requests and set the headers accordingly:
...
after_filter :cors_set_access_control_headers
def cors_set_access_control_headers
headers['Access-Control-Allow-Origin'] = '*'
headers['Access-Control-Allow-Methods'] = 'POST, GET, PUT' # etc. etc.
headers['Access-Control-Max-Age'] = "1728000"
end
...
For more extensive examples on how to configure CORS for rails you could search for "CORS for JSON and Rails" for example.
Hope it helps