how to fix make_response error by adding mimetype to json data ty pe in Flask - flask

I am trying to make slurm-web code working.
in restapi.py, there is a def sinfo() method which reads as follows:
#app.route('/sinfo', methods=['GET', 'OPTIONS'])
#crossdomain(origin=origins, methods=['GET'],
headers=['Accept', 'Content-Type', 'X-Requested-With', 'Authorization'])
#authentication_verify()
def sinfo():
# Partition and node lists are required
# to compute sinfo informations
partitions = get_from_cache(pyslurm.partition().get, 'get_partitions')
nodes = get_from_cache(pyslurm.node().get, 'get_nodes')
# Retreiving the state of each nodes
nodes_state = dict(
(node.lower(), attributes['state'].lower())
for node, attributes in nodes.iteritems()
)
# For all partitions, retrieving the states of each nodes
sinfo_data = {}
for name, attr in partitions.iteritems():
for node in list(NodeSet(attr['nodes'])):
key = (name, nodes_state[node])
if key not in sinfo_data.keys():
sinfo_data[key] = []
sinfo_data[key].append(node)
# Preparing the response
resp = []
for k, nodes in sinfo_data.iteritems():
name, state = k
partition = partitions[name]
avail = partition['state'].lower()
min_nodes = partition['min_nodes']
max_nodes = partition['max_nodes']
total_nodes = partition['total_nodes']
job_size = "{0}-{1}".format(min_nodes, max_nodes)
job_size = job_size.replace('UNLIMITED', 'infinite')
time_limit = partition['max_time_str'].replace('UNLIMITED', 'infinite')
# Creating the nodeset
nodeset = NodeSet()
map(nodeset.update, nodes)
resp.append({
'name': name,
'avail': avail,
'job_size': job_size,
'time_limit': time_limit,
'nodes': total_nodes,
'state': state,
'nodelist': str(nodeset),
})
# Jsonify can not works on list, thus using json.dumps
# And making sure headers are properly set
return make_response(json.dumps(resp), mimetype='application/json')
apache error log says that
return make_response(json.dumps(resp), mimetype='application/json')
TypeError: make_response() got an unexpected keyword argument 'mimetype'
I am using flase 1.0.2 and wondering what makes this error.

First, you'll need to indent that return so that it happens at the end of sinfo(). Then you can simplify by writing
from flask import jsonify
...
def sinfo():
...
return jsonify(resp)

Related

list indices must be integers or slices, not dict in django

I just want to iterate through the list of JSON data which I get in the payload but getting an error as list indices must be integers or slices, not dict
payload:
[{"AuditorId":10,"Agents":"sa","Supervisor":"sa","TicketId":"58742","QId":150,"Answer":"Yes","TypeSelected":"CMT Mails","Comments":"na","TicketType":"Regularticket","Action":"na","AuditSubFunction":"na","AuditRegion":"na"},{"AuditorId":10,"Agents":"sa","Supervisor":"sa","TicketId":"58742","QId":151,"Answer":"Yes","TypeSelected":"CMT Mails","Comments":"na","TicketType":"Regularticket","Action":"na","AuditSubFunction":"na","AuditRegion":"na"}]
views.py:
#api_view(['POST'])
def SaveUserResponse(request):
for ran in request.data:
auditorid = request.data[ran].get('AuditorId')
ticketid = request.data[ran].get('TicketId')
qid = request.data[ran].get('QId')
answer = request.data[ran].get('Answer')
sid = '0'
TicketType = request.data[ran].get('TicketType')
TypeSelected = request.data[ran].get('TypeSelected')
agents = request.data[ran].get('Agents')
supervisor = request.data[ran].get('Supervisor')
Comments = request.data[ran].get('Comments')
action = request.data[ran].get('Action')
subfunction = request.data[ran].get('AuditSubFunction')
region = request.data[ran].get('AuditRegion')
cursor = connection.cursor()
cursor.execute('EXEC [dbo].[sp_SaveAuditResponse] #auditorid=%s,#ticketid=%s,#qid=%s,#answer=%s,#sid=%s,#TicketType=%s,#TypeSelected=%s,#agents=%s, #supervisor =%s, #Comments=%s, #action=%s, #subfunction=%s, #region=%s',
(auditorid,ticketid,qid,answer, sid,TicketType, TypeSelected, agents, supervisor, Comments, action, subfunction,region))
return Response(True)
I ran this code on my machine and it works for the payload you provided.
#api_view(['POST'])
def SaveUserResponse(request):
for ran in request.data:
auditorid = ran.get('AuditorId')
ticketid = ran.get('TicketId')
qid = ran.get('QId')
answer = ran.get('Answer')
sid = '0'
TicketType = ran.get('TicketType')
TypeSelected = ran.get('TypeSelected')
agents = ran.get('Agents')
supervisor = ran.get('Supervisor')
Comments = ran.get('Comments')
action = ran.get('Action')
subfunction = ran.get('AuditSubFunction')
region = ran.get('AuditRegion')
If it doesn't then content of request.data must be different then payload you shared in original post

django filter data and make union of all data points to assignt to a new data

My model is as follows
class Drawing(models.Model):
drawingJSONText = models.TextField(null=True)
project = models.CharField(max_length=250)
Sample data saved in drawingJSONText field is as below
{"points":[{"x":109,"y":286,"r":1,"color":"black"},{"x":108,"y":285,"r":1,"color":"black"},{"x":106,"y":282,"r":1,"color":"black"},{"x":103,"y":276,"r":1,"color":"black"},],"lines":[{"x1":109,"y1":286,"x2":108,"y2":285,"strokeWidth":"2","strokeColor":"black"},{"x1":108,"y1":285,"x2":106,"y2":282,"strokeWidth":"2","strokeColor":"black"},{"x1":106,"y1":282,"x2":103,"y2":276,"strokeWidth":"2","strokeColor":"black"}]}
I am trying to write a view file where the data is filtered based on project field and all the resulting queryset of drawingJSONText field are made into one data
def load(request):
""" Function to load the drawing with drawingID if it exists."""
try:
filterdata = Drawing.objects.filter(project=1)
ids = filterdata.values_list('pk', flat=True)
length = len(ids)
print(list[ids])
print(len(list(ids)))
drawingJSONData = dict()
drawingJSONData = {'points': [], 'lines': []}
for val in ids:
if length >= 0:
continue
drawingJSONData1 = json.loads(Drawing.objects.get(id=ids[val]).drawingJSONText)
drawingJSONData["points"] = drawingJSONData1["points"] + drawingJSONData["points"]
drawingJSONData["lines"] = drawingJSONData1["lines"] + drawingJSONData["lines"]
length -= 1
#print(drawingJSONData)
drawingJSONData = json.dumps(drawingJSONData)
context = {
"loadIntoJavascript": True,
"JSONData": drawingJSONData
}
# Editing response headers and returning the same
response = modifiedResponseHeaders(render(request, 'MainCanvas/index.html', context))
return response
I runs without error but it shows a blank screen
i dont think the for function is working
any suggestions on how to rectify
I think you may want
for id_val in ids:
drawingJSONData1 = json.loads(Drawing.objects.get(id=id_val).drawingJSONText)
drawingJSONData["points"] = drawingJSONData1["points"] + drawingJSONData["points"]
drawingJSONData["lines"] = drawingJSONData1["lines"] + drawingJSONData["lines"]

Django single object update in for loop

Hi I'm wondering if it possible or how to update single model object name inside for loop by his id using object.filter(pk=id).update(name='name') function
I try to do this but its not working in for loop. It's working only outside loop
EDIT
my edit view with for loop:
first i prepare data based on my database.Data can be modified by other methods so i keep they in global list schedule_table.
When I'm saving project object i want to update other data representing by schedule_table, using for loop.
def ProjectEditView(request, pk):
project = get_object_or_404(Project, pk=17)
schedule_table_load_form_db(project)#preparing list with data
Task_Schedule_TableView(request)
project_form = ProjectForm(request.POST or None, instance=project)
project_form_valid = project_form.is_valid()
if project_form_valid:
with transaction.atomic():
# save form in DB
project = project_form.save(commit=False)
project.save()
# modify other object based on changed list schedule_table
if schedule_table.__len__() > 0:
#my for loop
for p in schedule_table:
team = Team.objects.get(name=p.team)
phase = Phase.objects.filter(pk=p.pk).update(name=p.name,
project=project,
team=team,
order=p.order,
duration=p.duration,
prev=p.prev,
start=p.start,
end=p.end)
# some other staff..... outside the loop
return redirect('Project:ProjectListView')
context = {'project_form': project_form}
return render(request, 'Project/test.html', context)
function to prepare list with data:
def schedule_table_load_form_db(project):
global schedule_table
schedule_table = []
phases = Phase.objects.filter(project=project)
for phase in phases:
tasks_list = Task.objects.filter(phase=phase)
tasks = []
for task in tasks_list:
task_dict = Task_dictionary.objects.get(pk=task.task_dictionary.pk)
tmp = ''
for e in task.employers.employer.all():
user = User.objects.get(pk=e.user_id)
tmp += user.first_name + ' ' + user.last_name + ','
tasks.append(TableTask(pk=task.pk,
order=task.order,
name=task.name,
duration=task.duration,
employer=tmp,
start=task.start,
end=task.end,
min_employers_nr=task_dict.min_employers_nr,
max_employers_nr=task_dict.max_employers_nr,
prev=task.prev_task,
))
schedule_table.append(TablePhase(pk=phase.pk,
name=phase.name,
duration=0.0,
start=phase.start,
end=phase.end,
team=phase.team.name,
task=tasks,
order=schedule_table.__len__(),
prev=phase.prev
))

How to save result of a function into a string so it can be sent via email (using smtplib and MIME)?

I am new to Python and very much a rookie. I am trying to write a program that uses the requests module to make a request to the Dark Sky API for a weather forecast, and then uses smtplib to send that forecast in an email to myself. I have truncated my code to only show the relevant parts. I have been unable to find any answers so far so I apologise if this is a duplicate. The below code will print the function to the console without any issues, but when I try to assign it to the "body" variable and email it, the email is blank. Or if I use str(ds.current)) the email just has "none" as the body text.
How can I make it work so that the body text of the email contains the forecast that has been requested from the API? Many thanks in advance, and sorry for any rookie errors.
import requests
import json
import smtplib
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
class Darksky():
r = requests.get('https://api.darksky.net/forecast/e01635ccacb5548e3d1fa40403bbb3a5/-45.0312,168.6626?units=ca')
wx_json = r.json()
def __init__(self, source):
self.source = source
print "\n", "-" * 20, source, "-" * 20, "\n"
def current(self):
def summary():
return "CURRENT WEATHER:"
x = self.wx_json['currently']['summary']
return x
# I have tried using print instead of return but that did not work either.
def temp():
return "TEMPERATURE:"
y = self.wx_json['currently']['temperature']
return y
summary()
temp()
ds = Darksky("DARKSKY WX")
fromaddr = "watsonthevirtualbutler#gmail.com"
toaddr = "matt#peakpixel.nz"
msg = MIMEMultipart()
msg['From'] = fromaddr
msg['To'] = toaddr
msg['Subject'] = "YOUR DAILY WEATHER, SIR."
body = ds.current()
# This is where I am trying to save the function result as a string that can be emailed.
# I have tried using "str(ds.current())" but that just returns "none".
print body
msg.attach(MIMEText(body, 'plain'))
server = smtplib.SMTP('smtp.gmail.com', 587)
server.starttls()
server.login(fromaddr, "virtualbutler")
text = msg.as_string()
msg = "CAN YOU HEAR ME, SIR?"
server.sendmail(fromaddr, toaddr, text)
server.quit()
Your summary() and temp() has two return operators, while only one return is acceptable. If you want your_function() to return few values, you can do something like: return {"first_parameter": "first_value", "second_parameter": "second_value"} and then call each value as your_function()["first_parameter"] or your_function()["second_parameter"]
Try following code and let me know the result:
class Darksky():
r = requests.get('https://api.darksky.net/forecast/e01635ccacb5548e3d1fa40403bbb3a5/-45.0312,168.6626?units=ca')
wx_json = r.json()
def __init__(self, source):
self.source = source
print "\n", "-" * 20, source, "-" * 20, "\n"
def current(self):
return "CURRENT WEATHER: {0}. TEMPERATURE: {1}".format(self.wx_json['currently']['summary'], self.wx_json['currently']['temperature'])
ds = Darksky("DARKSKY WX")
body = ds.current()

Using Python Tkinter .config() method

I am trying to use the Python Tkinter .config() method to update some message text. I can't get it to work. What might I be doing wrong (see the update_message method):
#!/usr/bin/python
import alsaaudio as aa
import audioop
import Tkinter as tk
import tkFont
import threading
import Queue
# styles
BACKROUND_COLOR = '#000000'
TYPEFACE = 'Unit-Bold'
FONT_SIZE = 50
TEXT_COLOR = '#777777'
TEXTBOX_WIDTH = 400
# text
TITLE = 'listen closely'
SCORE_MESSAGE = 'your score:\n '
END_MESSAGE = 'too loud!\ntry again'
# configuration
DEVICE = 'hw:1' # hardware sound card index
CHANNELS = 1
SAMPLE_RATE = 8000 # Hz // 44100
PERIOD = 256 # Frames // 256
FORMAT = aa.PCM_FORMAT_S8 # Sound format
NOISE_THRESHOLD = 3
class Display(object):
def __init__(self, parent, queue):
self.parent = parent
self.queue = queue
self._geom = '200x200+0+0'
parent.geometry("{0}x{1}+0+0".format(
parent.winfo_screenwidth(), parent.winfo_screenheight()))
parent.overrideredirect(1)
parent.title(TITLE)
parent.configure(background=BACKROUND_COLOR)
parent.displayFont = tkFont.Font(family=TYPEFACE, size=FONT_SIZE)
self.process_queue()
def process_queue(self):
try:
score = self.queue.get(0)
self.print_message(score)
except Queue.Empty:
pass
self.parent.after(100, self.update_queue)
def update_queue(self):
try:
score = self.queue.get(0)
self.update_message(score)
except Queue.Empty:
pass
self.parent.after(100, self.update_queue)
def print_message(self, messageString):
print 'message', messageString
displayString = SCORE_MESSAGE + str(messageString)
self.message = tk.Message(
self.parent, text=displayString, bg=BACKROUND_COLOR,
font=self.parent.displayFont, fg=TEXT_COLOR, width=TEXTBOX_WIDTH, justify="c")
self.message.place(relx=.5, rely=.5, anchor="c")
def update_message(self, messageString):
print 'message', messageString
displayString = SCORE_MESSAGE + str(messageString)
self.message.config(text=displayString)
def setup_audio(queue, stop_event):
data_in = aa.PCM(aa.PCM_CAPTURE, aa.PCM_NONBLOCK, 'hw:1')
data_in.setchannels(2)
data_in.setrate(44100)
data_in.setformat(aa.PCM_FORMAT_S16_LE)
data_in.setperiodsize(256)
while not stop_event.is_set():
# Read data from device
l, data = data_in.read()
if l:
# catch frame error
try:
max_vol = audioop.rms(data, 2)
scaled_vol = max_vol // 4680
print scaled_vol
if scaled_vol <= 3:
# Too quiet, ignore
continue
queue.put(scaled_vol)
except audioop.error, e:
if e.message != "not a whole number of frames":
raise e
def main():
root = tk.Tk()
queue = Queue.Queue()
window = Display(root, queue)
stop_event = threading.Event()
audio_thread = threading.Thread(target=setup_audio,
args=[queue, stop_event])
audio_thread.start()
try:
root.mainloop()
finally:
stop_event.set()
audio_thread.join()
pass
if __name__ == '__main__':
main()
I don't want to be laying down a new message every time I update. If the .config() doesn't work, is there another method to update the text configuration of the message?
I would use string variables, first create your string variable then set it to want you want it to display at the start next make your object and in text put the sting variable then when you want to change the text in the object change the string variable.
self.messaget = StringVar()
self.messaget.set("")
self.message = tk.Message(
self.parent, textvariable=self.messaget, bg=BACKROUND_COLOR,
font=self.parent.displayFont, fg=TEXT_COLOR,
width=TEXTBOX_WIDTH, justify="c").grid()
#note renember to palce the object after you have created it either using
#.grid(row = , column =) or .pack()
#note that it is textvariable instead of text if you put text instead it will run but
#but will show PY_Var instead of the value of the variable
edit
to change the text without recreating the object you do the name of the string variable you have used and .set
self.messaget.set("hi")