Python Hug REST API consumed in .NET, JSON looks weird - python

When consuming a Hug REST endpoint from .net JSON has embedded characters. A complete failing example posted below. Any help greatly appreciated.
Python
#hug.post('/test')
def test(response, body=None):
input = body.get('input')
print('INSIDE TEST ' + input)
if input:
dict = {"lastname":"Jordan"}
dict["firstname"] = input
return json.dumps(dict, sort_keys=True, default=str)
.NET (can only use .net 3.5)
private static object GetParsedData(string data)
{
var posturl = "http://localhost:8000/test";
try
{
using (var client = new WebClient())
{
// upload values is the POST verb
var values = new NameValueCollection()
{
{ "input", data },
};
var response = client.UploadValues(posturl, values);
var responseString = Encoding.UTF8.GetString(response);
var settings = new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore,
MissingMemberHandling = MissingMemberHandling.Ignore
};
JObject rss = JObject.Parse(responseString);
Console.WriteLine((string)rss["lastname"]);
}
}
catch (WebException ex)
{
if (ex.Response is HttpWebResponse)
{
var code = ((HttpWebResponse)ex.Response).StatusCode;
var desc = ((HttpWebResponse)ex.Response).StatusDescription;
}
//_logger.Error(ex.Message);
}
return false;
}
responseString looks like this:
"\"{\\\"firstname\\\": \\\"Mike\\\", \\\"lastname\\\": \\\"Jordan\\\"}\""
JObject.Parse throws error:
Newtonsoft.Json.JsonReaderException:
'Error reading JObject from JsonReader. Current JsonReader item is not an object: String. Path '', line 1, position 53.
Workaround - If I do something horrible like this to responseString JObject parses correctly:
str = str.Replace("\\", "");
str = str.Substring(1, len - 2);
Whats going on?

The default hug output format is json; it is not necessary to call json.dumps on return values, hug will do this automatically.

Related

Error 500 InternalServerError when use httprequest call API (python flask) with long time response

I build a service to call API from Python flask. This is my Service
public string CheckStatus(string json)
{
Utils log = new Utils();
string ResponseString = "";
HttpWebResponse response = null;
try
{
string schedulingAPIUrl = ConfigurationManager.AppSettings["SchedulingAPI_URL"];
var request = (HttpWebRequest)WebRequest.Create(string.Format(schedulingAPIUrl + "{0}", "CheckStatus"));
request.Accept = "application/json";
request.Method = "POST";
request.Timeout = Timeout.Infinite;
request.KeepAlive = true;
var myContent = json;
var data = Encoding.ASCII.GetBytes(myContent);
request.ContentType = "application/json";
request.ContentLength = data.Length;
using (var stream = request.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
response = (HttpWebResponse)request.GetResponse();
ResponseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
}
catch (WebException ex)
{
if (ex.Status == WebExceptionStatus.ProtocolError)
{
response = (HttpWebResponse)ex.Response;
ResponseString = "Some error occurred: " + response.StatusCode.ToString();
}
else
{
ResponseString = "Some error occurred: " + ex.Status.ToString();
}
}
return ResponseString;
}
My Service will transfer a parameter is a list of many dictionaries to my API. If the Parameter has an amount of ~ 10000 dictionaries, everything is ok. But If it has to amount to 1 million dictionaries or more, after my API run 8-10minutes, I get an error: "500 InternalServerError".
I use wfastcgi, IIS to deploy my API.
I don't know the reason for the 500 error being from my Service or my API.

extract aws lambda exception response in c#

I have a lambda function where I am making an api call which returns uuid on success and errorMessage on failure
try:
#make api call
return {
'statusCode': 200,
'body': json.dumps({'uuid':uniqueuuid})
}
except Exception as error:
return {
'statusCode': 500,
'body': json.dumps({'errorMessage':f"P56"})
}
For the success response from lambda, I can able to extract the body values in C#. In the below method,
I can able to get the uuid value returned from lambda. But when there is an exception from lambda, I want to
extract the errorMessage value which is "P56". On exception from lambda, it is picked up by catch block
and the exception has 'remote server returned an error 500' which is correct, but how do I extract the status code and errorMessage value in
the exception block. Or should I return statusCode as 200 for both success and failure from lambda
and extract either uuid or errorMessage in the try block of C#.
C# method:
private JObject GetDataFromLambda()
{
JObject jObj = null;
try
{
using (var client = new WebClient())
{
//define payload data
var result = client.UploadString($"https://xxx",
WebRequestMethods.Http.Post, data)
jObj = JObject.Parse(result);
var uuid= jObj["uuid"].Value<string>();
}
}
catch (Exception ex)
{
}
}
Can you try writing the below code in Lambda?
raise Exception('Something is wrong')
Based on the documentation, something like this should work:
private JObject GetDataFromLambda(string data)
{
JObject jObj = null;
try
{
using (var client = new WebClient())
{
//define payload data
var result = client.UploadString($"https://xxx",
WebRequestMethods.Http.Post, data)
jObj = JObject.Parse(result);
var uuid = jObj["uuid"].Value<string>();
}
}
catch (WebException ex)
{
if (ex.Status == WebExceptionStatus.ProtocolError)
{
var response = (HttpWebResponse)ex.Response;
var encoding = System.Text.Encoding.UTF8;
var sr = new StreamReader(response.GetResponseStream(), encoding);
string json = sr.ReadToEnd();
var errObj = JObject.Parse(json);
var httpStatusCode = response.StatusCode;
var errorMessage = errObj["errorMessage"].Value<string>();
}
}
return jObj;
}
Documentation:
WebException.Response: https://learn.microsoft.com/en-us/dotnet/api/system.net.webexception.response?view=net-6.0#system-net-webexception-response
HttpWebResponse.GetResponseStream(): https://learn.microsoft.com/en-us/dotnet/api/system.net.httpwebresponse.getresponsestream?view=net-6.0#system-net-httpwebresponse-getresponsestream

Python web request in unity3d webrequest

Here this is code of python about web request. Can we do this same python code with Unity3D webrequest.
Code.
import requests
r = requests.post(
"https://api.deepai.org/api/torch-srgan",
files={
'image': open('/path/to/your/file.jpg', 'rb'),
},
headers={'api-key': '535d7326-c37f6105b0'}
)
print(r.json())
You would use a UnityWebRequest.Post using the overload that takes a List<IMultipartFormSection> and actually use a MultipartFormFileSection
Should be something like
var bytes = File.ReadAllBytes("/path/to/your/file.jpg");
var data = new List<IMultipartFormSection>();
data.Add(new MultipartFormFileSection("image", bytes, "file.jpg", "image/jpeg"));
using(var request = UnityWebRequest.Post("https://api.deepai.org/api/torch-srgan"))
{
request.SetRequestHeader("api-key", "535d...........");
yield return request.SendWebRequest();
if (request.result != UnityWebRequest.Result.Success)
{
Debug.Log(request.error);
}
else
{
Debug.Log("Form upload complete!");
Debug.Log(request.downloadHandler.text);
}
}
Then for parsing the JSON result you can use e.g.
[Serializable]
public class Response
{
public string id;
public string output_url;
}
and then do
....
var response = JsonUtility.FromJson<Response>(request.downloadHandler.text);
Debug.Log(response.output_url);

https get request python (HTTPS / SSL)

So i'm working on converting a java program I have over to python. In my java code I have a http get call that looks like this.
sslContext.init(null, new TrustManager[] { new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
} }, new SecureRandom());
try {
CloseableHttpClient httpclient = HttpClients.custom()
.setSSLSocketFactory(new org.apache.http.conn.ssl.SSLSocketFactory(sslContext)).build();
String authString = username + ":" + password;
byte[] authEncBytes = Base64.encodeBase64(authString.getBytes());
String authStringEnc = new String(authEncBytes);
HttpGet httpGet = new HttpGet(envURL);
httpGet.setHeader("Content-Type", "application/json");
httpGet.setHeader("Authorization", "Basic " + authStringEnc);
CloseableHttpResponse httpGetResponse = httpclient.execute(httpGet);
HttpEntity entityResponse = httpGetResponse.getEntity();
String result = EntityUtils.toString(entityResponse);
EntityUtils.consume(entityResponse);
JSONParser parser = new JSONParser();
thresholdContent = (JSONArray) parser.parse(result);
} catch (Exception e) {
e.printStackTrace();
}
i'm trying to find the cleanist way to do this in python 3.x. Or I guess the standered for doing something like this in python.
I've tried soemthing like:
conn = requests.get(env, headers={"content-type":"application/json"}, auth=(userName,password))
but have not had much luck.
With requests in python you need to pass the url
conn = requests.get(url = 'https://myurl', headers = {'Content-Type':'application/json'})

In AngualrJS using $http, how to get the value of a variable set in Python CGI?

I'm making a POST request from AngularJS to Python.
I started with an JavaScript example. It works properly returning all the values.
However, when I try to do it from AngularJS I'm not able to read the value of the variable posted.
JAVASCRIP EXAMPLE THAT WORKS PROPERLY (I'm able to get the value (Mike) back of Name):
JS code
<script language="Javascript">
function asyncChange()
{
var request;
if (window.XMLHttpRequest) {
request = new window.XMLHttpRequest();
} else {
// Versiones antiguas de Internet Explorer.
request = new window.ActiveXObject("Microsoft.XMLHTTP");
}
request.open("POST","nctest.py" , true);
request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
request.send("Name=Mike");
request.onreadystatechange = function()
{
if (request.readyState == 4 && request.status == 200)
{
document.getElementById("myLabel").innerHTML = "Hello " + request.responseText + "!";
}
}
}
</script>
nctest.py
#!/usr/bin/python
import cgi
input = cgi.FieldStorage()
print "Content-type: text/html\n\n"
print "input[Pe].value: "
print input["Pe"].value
ANGULARJS DOESN'T WORK PROPERLY (I'm not able to get the value (Mike) back of Name):
Angularjs code:
(function(){
'use strict'
var sectest= {
controller:sectestCtrl,
templateUrl:'app/components/component_test/test.html',
}
angular
.module('myapp')
.component('secTest',sectest);
function sectestCtrl($http){
var prac= this;
prac.method = 'POST';
prac.url = 'nctest.py';
prac.data = {Name : 'Mike'};
prac.data_answer
prac.headers = { 'Content-Type': 'application/x-www-form-urlencoded' };
prac.sendHTML = send;
function send(){
prac.code = null;
prac.response = null;
$http({method: prac.method, headers: prac.headers, url: prac.url, data: $.param(prac.data)}).
then(function(response) {
prac.status = response.status;
prac.data_answer = response.data;
console.log("OK prac.data_answer: ", prac.data_answer)
}, function(response) {
prac.data_answer = response.data || 'Request failed';
prac.status = response.status;
});
};
}
})();
nctest.py code
#!/usr/bin/python
import json
import cgi
input = cgi.FieldStorage()
print "Content-type: text/html\n\n"
print input["Name"].value
The problem is that prac.data_answer prints blank value.
I have already try with different headers for both angularjs and python codes but none seems to work:
prac.headers = { 'Content-Type': 'application/json' };
prac.headers = { 'Content-Type': 'application/x-www-form-urlencoded' };
prac.headers = { 'Content-Type': 'text/html\n\n' };
Many thanks.
There are 2 separate issues you're trying to address. Server (CGI) & client(angularjs). First check to see that you are receiving the data over the network - using Chrome developer tools, under the Network tab. If so, there's no need to change the Content-Type to json, since angular by default assumes all http data is in json format.
I don't think you need all those attributes for a post request. Seems like an overkiller when it can be simpler. Try this:
$http.post(url, data).then(function(response){
console.log(response.data);
});

Categories