how to load data from a flask url and console log the data n react? - json

I want to load a json file that I get from a url generated in flask.
After d3.json(url, function) I'm trying to console log the json, but nothing happens and I dont know what's wrong. So maybe someone can help
This is basically my code:
Component where I want to display a graph (Display.js):
import React, { Component } from 'react';
import "./Display.css";
import * as d3 from "d3";
export default class Display extends Component {
componentWillReceiveProps() {
const url = "http://localhost:5000/company?company_name=" + this.props.inputDataFromParent //the url depends on the input the user made. InputDataFromParent is the passed value (from the parent) that the user typed in
d3.json(url, function (data) {
console.log(data)
})
}
when I type in an input (company name) that doesnt exist in the database I get an error: "Uncaught (in promise) SyntaxError: Unexpected token N in JSON at position 0"at (index):1
when I type in an input that does exist nothing happens in the console.
Here's my main.py:
import flask
from pandas import DataFrame
from models import company_search
from flask import request
from models import subsidiaries
app=flask.Flask("__main__")
#app.route("/company")
def result():
if request.method == 'GET':
company_name = request.args.get('company_name', None)
if company_name:
return subsidiaries(company_name)
return "No place information is given"
app.run(debug=True)
and this is models.py (neo4j is used as the database):
def subsidiaries(eingabe):
if regex_eingabe_kontrolle(eingabe):
namelistdf = graph.run("MATCH (c:Company)-[rel:Relation]->(d:Company) WHERE rel.relation_group='OWNERSHIP' AND rel.percent_share >= 50 AND c.company_name= $eingabe RETURN c, rel, d",eingabe=eingabe).to_data_frame()
if namelistdf.empty:
return "No company with this name exists"
namelistjson = namelistdf.to_json(orient="records",date_unit="s",default_handler=str)
return namelistjson
else:
return "Please enter a valid company name"
I get the data from a neo4j database.
It's not about to console log the data because I want to generate a graph from the data. The console log is only for testing if the data is right. But now it seems that the data isn't passed to d3.json(url, function (data) correctly

Your problem occurs in your main file when you return No place information is given. Since this is not in JSON format, JavaScript fails to parse it causing the error to be thrown. To fix this, you can change it to:
import json
#app.route("/company")
def result():
if request.method == 'GET':
company_name = request.args.get('company_name', None)
if company_name:
return subsidiaries(company_name)
return json.dumps("No place information is given")
If you do the same for No company with this name exists and Please enter a valid company name, you won't get anymore JSON deserialization errors. However, D3 may still throw errors because it does not know what to do with a string.
You may want to return HTTP status codes along with your error messages so you can control the error. To do this in Flask, you can return the text along with the status code. For example: return json.dumps("Error message"), 400 will return the JSON string Error message with the status code 400. Since d3.json makes an underlying call to the JavaScript fetch function, you should be able to access the status code by using data.status.

Related

How to retrieve data from self-made restfull_api

I trying to retrieve the information from my API via Y/views.py from another app in the same project. I am receiving the following error ([WinError 10061]). Although, i am able to perform get/post/put via my json_main.js. Thanks to all who support me in this journey. Please read what is already working. And as additional question I would ask why it is not possible to retrieve the data directly via my model/sqlite db.
I already created the following:
X/Views + X/Template.html. X/Views renders information from the backend to the X/template.html. Within this template there is a JSON script(working) that performs a POST/GET/PUT to the API(working) on image click.
The function ultimately results in a new record in API/Bestellingen. The information stored via this JSON function (incl. token authentication; csrf) should now be retrieved in the views.py of Y/view. I already created an example dict. that is rendered to Y/template.html
I tried several JSON request methods (coreapi, urllib2, urllib3, requests), but keep receiving the error as mentioned before. As already stated: JSON.js script does work. Doing the same via POSTMAN also works.
Since i am performing the same via .js and postman, I am quite sure that the variables (token, header and the request) should be ok.
I will show some short snippets of already working code. Herafter i will show the code that doesn't seem to work.
Information from X/views.py -> X/template.html
return render(request, 'smaakjes/smaakjes.html', {'Drank': super_dict})
X/Template.html (see onclick ="")
{% for key, value_list in Drank.items %}
<img onclick="PostImageDetails(this)" style="margin: 0 auto;" src="{{ value }}" id="{{ value }}">
JSON.js (works), sends information to http:127:0:0:0:8000/api/bestellingen. I can see the stored information via the API view.
xmlhttp.send(JSON.stringify({'url':imageSrc, 'username': imageId}))
Y/views.py -> renders information to Y/template.html(works)
def BestellingenDashboard(request):
Data = {'iets': '1'}
return render(request, 'homepage.html', {'bestellingen' : Data})
Once information has been stored in the API/bestellingen, I would like to retrieve the whole json dict. via python Y/Views.py and store it in the above 'Data'(that's ofc easy :)). Does somebody know what i am doing wrong? Why is postman working? Am i Missing a header or something? In my opinion, retrieving data from your own API should be very easy :D
from django.http import HttpResponse
from django.shortcuts import render
from api.models import Bestellingen
import json
import secrets
import requests
URL = "http://127.0.0.1:8000/api/bestellingen/"
data_json = json.dumps(data)
payload = {'json_payload': data_json}
r = requests.get(url=URL, headers={'Content-Type': 'application/json', 'token' : secrets.token_hex(40)}, json=payload)
a = r.json()
print(a)
def BestellingenDashboard(request):
Data = {'iets': '1'}
return render(request, 'homepage.html', {'bestellingen' : Data})
As you can read, most is working (api, endpoints, apiviews, rendering info from X-X.html,X.html->API. I now want to get the information in Y.views, so that i can use this information in Y/template.html

Format ValidationError in Serializer

DjangoRestFramework seems to handle errors with a variety of ways. The ValidationError in the serializer class does not consistently return JSON the same.
Current response includes a JSON list/object string:
{"detail":["Unable to log in with provided credentials."]}
Looking to achieve:
{"detail":"Unable to log in with provided credentials."}
I realize that this response is a result of default functions. However, I've overridden the validate function:
class AuthCustomTokenSerializer(serializers.Serializer):
username = serializers.CharField(write_only=True)
password = serializers.CharField(write_only=True)
token = serializers.CharField(read_only=True)
def validate(self, validated_data):
username = validated_data.get('username')
password = validated_data.get('password')
# raise serializers.ValidationError({'detail': 'Unable to log in with provided credentials.'})
if username and password:
user = authenticate(phone_number=username, password=password)
try:
if UserInfo.objects.get(phone_number=username):
userinfo = UserInfo.objects.get(phone_number=username)
user = User.objects.filter(user=userinfo.user, password=password).latest('date_joined')
if user:
if user.is_active:
validated_data['user'] = user
return validated_data
else:
raise serializers.ValidationError({"detail": "User account disabled."})
except UserInfo.DoesNotExist:
try:
user = User.objects.filter(email=username, password=password).latest('date_joined')
if user.is_active:
validated_data['user'] = user
return validated_data
except User.DoesNotExist:
#raise serializers.ValidationError("s")
raise serializers.ValidationError({'detail': 'Unable to log in with provided credentials.'})
else:
raise serializers.ValidationError({"detail" : "Must include username and password."})
class Meta:
model = Token
fields = ("username", "password", "token")
I've tried adding a custom exception handler:
from rest_framework.views import exception_handler
def custom_exception_handler(exc, context):
# Call REST framework's default exception handler first,
# to get the standard error response.
response = exception_handler(exc, context)
# Now add the HTTP status code to the response.
if response is not None:
response.data['status_code'] = response.status_code
return response
views.py: if serializer.is_valid(raise_exception=True):
However, that only appends the currently raised error:
{"detail":["Unable to log in with provided credentials."],"status_code":400}
How should I use change the format of the returning text?
It only returns the JSON like this for this particular serializer within the validate function.
I've also looked into formatting the non_field_errors template, but it works with all my other serializers e.g:
{"detail": "Account exists with email address."}
Maybe you should try overriding json renderer class and hook up a custom one, where you can check for status code and detail key in response data, then re-format the value appropriately.
I never tried that, so I can't give you the exact codebase, but this is the only approach I can think of to have consistent response.

Returning JSON object from Django view to client via AJAX

Basically, I am trying to turn raw SQL query result to JSON object and then send it to client-side via AJAX.
Here is my view (I am using Django 1.8.6)
import MySQLdb
from django.db import connection
import json
from django.http import HttpResponse
from django.core import serializers
def test_view(request):
cursor = connection.cursor()
cursor.execute("select id, name from okved")
data = cursor.fetchall
json_data = serializers.serialize('json', data)
return HttpResponse(json_data, content_type="application/json")
The respective URLConf
url(r'^test/$', test_view),
JQuery function
var test = function()
{
$.ajax({
type:"GET",
url:"/test",
dataType : 'json',
cache: "false",
data:{},
success:function(response)
{
alert("Test successful");
}
});
return true;
}
I am constantly getting GET http://127.0.0.1:8000/test/ 500 (INTERNAL SERVER ERROR) error, wheareas I follow all the recommendations that I have come across the previous threads here. I would really appreciate any help on this. I have blown my mind trying surfing Stackoverflow on this.
First of all, 500 error is just an error code, django would give you stacktrace of where the error happens in the function stack, you should learn to read that and find where the error happens.
From you code sounds like you are trying to use serializers to serialize a raw query result. This wouldn't work because the raw result is a tuple of tuples, each sub tuple is a record returned from your database. Django serializers is only good at serializing objects queried from ORM. You'd better go with json.dumps() method. Here's last few lines in your views.py:
data = cursor.fetchall()
json_data = json.dumps(data)
return HttpResponse(json_data, content_type="application/json")
Here's the doc for django serializer.

OpenERP #http.route('demo_json', type="json") URL not displaying JSON Data

I am create controller in OpenERP Framework. Following is my code and i set http.route type="http",
import openerp.http as http
from openerp.http import request
class MyController(http.Controller):
#http.route('demo_html', type="http")
def some_html(self):
return "<h1>This is a test</h1>"
Above code work perfect once i login into openerp after i modify URL http://localhost:8069/demo_html show me return result This is a test in h1 heading tag.
But same way i try to type="json" and add following json code and again try to call URL http://localhost:8069/demo_json Its not work properly and show me error "Internal Server Error".
import openerp.http as http
from openerp.http import request
class MyController(http.Controller):
#http.route('demo_html', type="http") // Work Pefrect when I call this URL
def some_html(self):
return "<h1>This is a test</h1>"
#http.route('demo_json', type="json") // Not working when I call this URL
def some_json(self):
return {"sample_dictionary": "This is a sample JSON dictionary"}
So my question is how to route json. Any help would be appreciate Thank you.
This is because there is difference between type="json" and type="http".
type="json":
it will call JSONRPC as an argument to http.route() so here , there will be only JSON data be able to pass via JSONRPC, It will only accept json data object as argument.
type="http":
As compred to JSON, http will pass http request arguments to http.route() not json data.
I think , you need to do some extra stuff while working with type="json",you have to trigger that method using json rpc from js.
like :
$(document).ready(function () {
openerp.jsonRpc("demo_json", 'call', {})
.then(function (data) {
$('body').append(data[0]);
});
return;
})
and yes do not forget to return your dictionary in list like
#http.route('demo_json', type="json")
def some_json(self):
return [{"sample_dictionary": "This is a sample JSON dictionary"}]

How to JSON format an HTTP error response in webapp2

I am using webapp2 for development in App Engine. What I would like to do is to send a custom JSON formatted response in case of an error. For example when the request length is larger that a threshold, to respond with HTTP 400 and response body
{'error':'InvalidMessageLength'}
In webapp2, there is the option to assign error handlers for certain exceptions. For example:
app.error_handlers[400] = handle_error_400
Where handle_error_400 is the following:
def handle_error_400(request, response, exception):
response.write(exception)
response.set_status(400)
When webapp2.RequestHandler.abort(400) is executed, the above code is executed.
How is it possible to have different response formats (HTML and JSON) dynamically based on the above setup? That is, how it is possible to call different versions of handle_error_400 function?
Here is a fully working example that demonstrates how to have the same error handler for all kind of errors and if your URL starts with /json then the response will be an application/json (use your imagination on how you could make a good use of the request object to decide what kind of response you should provide):
import webapp2
import json
def handle_error(request, response, exception):
if request.path.startswith('/json'):
response.headers.add_header('Content-Type', 'application/json')
result = {
'status': 'error',
'status_code': exception.code,
'error_message': exception.explanation,
}
response.write(json.dumps(result))
else:
response.write(exception)
response.set_status(exception.code)
app = webapp2.WSGIApplication()
app.error_handlers[404] = handle_error
app.error_handlers[400] = handle_error
In the above example you can easily test the different behaviours by visting the following URLs that will return a 404 which is the easiest error to test:
http://localhost:8080/404
http://localhost:8080/json/404