convert object to json string after function that needs python dict - python

I have a python function/method that takes in a student and will show profile... i realized i need to return context as a json string. how do i do that?
context["student"] = db.query_dict(student_profile_sql.format(student_id=self.kwargs["student_id"])
)[0]
appear(self.request, "Show profile", {
"student_name": context["student"]["first_name...
})
return context // i need to return context as json string how can i do that?
How can i return context as a json string?

Import the json library:
import json
Then use json.dumps:
return json.dumps(context)
From the Python documentation:
json.dumps(obj, ...)
Serialize obj to a JSON formatted str

Related

Valid (?) JSON data causing errors in Django, must be served to frontend as string and converted by JSON.parse() in javascript - why?

I have a JSON file hosted locally in my Django directory. It is fetched from that file to a view in views.py, where it is read in like so:
def Stops(request):
json_data = open(finders.find('JSON/myjson.json'))
data1 = json.load(json_data) # deserialises it
data2 = json.dumps(data1) # json formatted string
json_data.close()
return JsonResponse(data2, safe=False)
Using JsonResponse without (safe=False) returns the following error:
TypeError: In order to allow non-dict objects to be serialized set the safe parameter to False.
Similarly, using json.loads(json_data.read()) instead of json.load gives this error:
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
This is confusing to me - I have validated the JSON using an online validator. When the JSON is sent to the frontend with safe=False, the resulting object that arrives is a string, even after calling .json() on it in javascript like so:
fetch("/json").then(response => {
return response.json();
}).then(data => {
console.log("data ", data); <---- This logs a string to console
...
However going another step and calling JSON.parse() on the string converts the object to a JSON object that I can use as intended
data = JSON.parse(data);
console.log("jsonData", data); <---- This logs a JSON object to console
But this solution doesn't strike me as a complete one.
At this point I believe the most likely thing is that there is something wrong with the source JSON - (in the file character encoding?) Either that or json.dumps() is not doing what I think it should, or I am not understanding the Django API's JSONresponse function in a way I'm not aware of...
I've reached the limit of my knowledge on this subject. If you have any wisdom to impart, I would really appreciate it.
EDIT: As in the answer below by Abdul, I was reformatting the JSON into a string with the json.dumps(data1) line
Working code looks like:
def Stops(request):
json_data = open(finders.find('JSON/myjson.json'))
data = json.load(json_data) # deserialises it
json_data.close()
return JsonResponse(data, safe=False) # pass the python object here
Let's see the following lines of your code:
json_data = open(finders.find('JSON/myjson.json'))
data1 = json.load(json_data) # deserialises it
data2 = json.dumps(data1) # json formatted string
You open a file and get a file pointer in json_data, parse it's content and get a python object in data1 and then turn it back into a JSON string and store it into data2. Somewhat redundant right? Next you pass this JSON string to JsonResponse which will further try to serialize it into JSON!! Meaning you then get a string inside a string in JSON.
Try the following code instead:
def Stops(request):
json_data = open(finders.find('JSON/myjson.json'))
data = json.load(json_data) # deserialises it
json_data.close()
return JsonResponse(data, safe=False) # pass the python object here
Note: function names in python should ideally be in snake_case not PascalCase, hence instead of Stops you should use stops. See
PEP 8 -- Style Guide for Python
Code

Can't convert a string to JSON using python 3? [duplicate]

This question already has answers here:
How can I parse (read) and use JSON?
(5 answers)
Closed 25 days ago.
In Python I'm getting an error:
Exception: (<type 'exceptions.AttributeError'>,
AttributeError("'str' object has no attribute 'read'",), <traceback object at 0x1543ab8>)
Given python code:
def getEntries (self, sub):
url = 'http://www.reddit.com/'
if (sub != ''):
url += 'r/' + sub
request = urllib2.Request (url +
'.json', None, {'User-Agent' : 'Reddit desktop client by /user/RobinJ1995/'})
response = urllib2.urlopen (request)
jsonStr = response.read()
return json.load(jsonStr)['data']['children']
What does this error mean and what did I do to cause it?
The problem is that for json.load you should pass a file like object with a read function defined. So either you use json.load(response) or json.loads(response.read()).
Ok, this is an old thread but.
I had a same issue, my problem was I used json.load instead of json.loads
This way, json has no problem with loading any kind of dictionary.
Official documentation
json.load - Deserialize fp (a .read()-supporting text file or binary file containing a JSON document) to a Python object using this conversion table.
json.loads - Deserialize s (a str, bytes or bytearray instance containing a JSON document) to a Python object using this conversion table.
You need to open the file first. This doesn't work:
json_file = json.load('test.json')
But this works:
f = open('test.json')
json_file = json.load(f)
If you get a python error like this:
AttributeError: 'str' object has no attribute 'some_method'
You probably poisoned your object accidentally by overwriting your object with a string.
How to reproduce this error in python with a few lines of code:
#!/usr/bin/env python
import json
def foobar(json):
msg = json.loads(json)
foobar('{"batman": "yes"}')
Run it, which prints:
AttributeError: 'str' object has no attribute 'loads'
But change the name of the variablename, and it works fine:
#!/usr/bin/env python
import json
def foobar(jsonstring):
msg = json.loads(jsonstring)
foobar('{"batman": "yes"}')
This error is caused when you tried to run a method within a string. String has a few methods, but not the one you are invoking. So stop trying to invoke a method which String does not define and start looking for where you poisoned your object.
AttributeError("'str' object has no attribute 'read'",)
This means exactly what it says: something tried to find a .read attribute on the object that you gave it, and you gave it an object of type str (i.e., you gave it a string).
The error occurred here:
json.load(jsonStr)['data']['children']
Well, you aren't looking for read anywhere, so it must happen in the json.load function that you called (as indicated by the full traceback). That is because json.load is trying to .read the thing that you gave it, but you gave it jsonStr, which currently names a string (which you created by calling .read on the response).
Solution: don't call .read yourself; the function will do this, and is expecting you to give it the response directly so that it can do so.
You could also have figured this out by reading the built-in Python documentation for the function (try help(json.load), or for the entire module (try help(json)), or by checking the documentation for those functions on http://docs.python.org .
Instead of json.load() use json.loads() and it would work:
ex:
import json
from json import dumps
strinjJson = '{"event_type": "affected_element_added"}'
data = json.loads(strinjJson)
print(data)
So, don't use json.load(data.read()) use json.loads(data.read()):
def findMailOfDev(fileName):
file=open(fileName,'r')
data=file.read();
data=json.loads(data)
return data['mail']
use json.loads() function , put the s after that ... just a mistake btw i just realized after i searched error
def getEntries (self, sub):
url = 'http://www.reddit.com/'
if (sub != ''):
url += 'r/' + sub
request = urllib2.Request (url +
'.json', None, {'User-Agent' : 'Reddit desktop client by /user/RobinJ1995/'})
response = urllib2.urlopen (request)
jsonStr = response.read()
return json.loads(jsonStr)['data']['children']
try this
Open the file as a text file first
json_data = open("data.json", "r")
Now load it to dict
dict_data = json.load(json_data)
If you need to convert string to json. Then use loads() method instead of load(). load() function uses to load data from a file so used loads() to convert string to json object.
j_obj = json.loads('["label" : "data"]')

How to Nifi ExecuteScript return attribute without prefix 'u' code python?

I have a json data incoming and I use ExecuteScript with Python code to extract key and value of this json data then put them into Attribute. Here my code:
import json
import java.io
from org.apache.commons.io import IOUtils
from java.nio.charset import StandardCharsets
from org.apache.nifi.processor.io import StreamCallback
class StreamCallback(StreamCallback):
def __init__(self):
pass
def process(self, inputStream, outputStream):
text = IOUtils.toString(inputStream, StandardCharsets.UTF_8)
data = json.loads(text)
for key in data:
first = key
break
content = data[first]
viewFlowFile = session.create()
viewFlowFile = session.putAllAttributes(viewFlowFile,{'project': str(first), 'content': str(content)})
session.transfer(viewFlowFile, REL_SUCCESS)
flowFile = session.get()
if flowFile != None:
flowFile = session.write(flowFile, StreamCallback())
session.transfer(flowFile, REL_FAILURE)
session.commit()
When I run Job ExecuteScript returns string with prefix 'u'.
My input:
{
"project_1": {
"device_code": "V001",
"line_code": "Anodiziing 12L"}}
and the output of content Attribute:
{
u'device_code': u'V001',
u'line_code': u'Anodiziing 12L'}
I also tried add
#!/usr/bin/python3
on header of body code. But there is no change.
My question is how to return string correctly without prefix 'u' using ExecuteScript Nifi?
Updated:
We need convert type of data from dictionary to string.
Using json.dumps(content) instead of str(content) and output will have no prefix 'u'.
JSON strings are Unicode. The u'' is just an indicator that the dictionary you are printing contains Unicode strings. If you don't want to see them, print the strings directly. If you were running Python 3, it doesn't use u'' for Unicode strings, as they are the default, but you would see b'' for byte strings.

Using JSON module to encode an object in Python

I have this String that I need to pass into a REST request
{"notification":{"tag":"MyTag"}}
I'm trying to turn into an object using the JSON module in python.
This is my attempt so far
import json
obj = json.dumps([{'notification': ('{tag : MyTag}')}])
But it isn't parsed correctly so the REST request won't work. Anyone have any ideas?
Just dump your dictionary as is, replace:
obj = json.dumps([{'notification': ('{tag : MyTag}')}])
with:
obj = json.dumps({"notification": {"tag": "MyTag"}})

Render template to escaped string for json in Django

This is more of a general python question, but it becomes a little more complicated in the context of Django.
I have a template, like this, simplified:
<span class="unit">miles</span>
I'm replacing an element with jquery and ajax:
$.getJSON('/getunit/', function(data){
$('#unitHolder').html(data.unit_html);
});
Which goes to a view function to retrieve json data (more data than just this template). So I wanted to serve it up as json, and not just a string. So, the relevant code is this:
...
context = { 'qs' : queryset }
data['unit'] = render_to_string('map/unit.html', context)
data = str(data).replace('\'','"') #json wants double quotes
return HttpResponse(data, mimetype="application/json")
This works for all of our other data, but not the template, because it has double quotes in it, that are not escaped. My question is, how do you escape a string in python to be used in a json format? Note that render_to_string() renders the string in unicode, thus u"<span>...</span>".
I've tried
import json
data['unit'] = json.dumps(render_to_string('map/unit.html', context))
But that gives me "unit": ""<span class=\\"unit\\">miles</span>"".
Also:
data['unit'] = str(render_to_string('map/unit.html', context)).replace('"','\"')
and:
data['unit'] = str(render_to_string('map/unit.html', context)).replace('"','\\"')
But neither escape the double quotes properly.
I hadn't tried json.dumps until I came into this problem. Previously I was just converting python dictionaries to strings and then replacing single quotes with double quotes. And for most of the data we've been passing to the client, it rendered correct JSON format. Now that I've tried json.dumps here in this problem, I realized that I don't need to convert dictionaries with str or replace anything. I can render the script as follows:
...
context = { 'qs' : queryset }
data['unit'] = render_to_string('map/unit.html', context)
import json # I'll import this earlier
data = json.dumps(data)
return HttpResponse(data, mimetype="application/json")
This works with all the data I'm passing to JSON format, so that works perfectly fine, and that's how I should have been doing it all along.

Categories

Resources