Flask jsonify print results on new lines - python

First time using Flask, I have created a very basic app and I am trying to print the results of a recommender system. The first set of code is from my python function (print_most_similar) and is creating a formatted string in hopes to print every REC on a new line. The second section of code is obviously my flask routing. You can see that the flask part calls the function, so it is returned 'y'.
I believe the jsonify will not take the \n characters.
I have tried using just '\n' in the string formatting, but it just appears as a string. As does '\t'.
for k in range(len(sugg)):
x = str("REC {}: {}\\n".format(k+1, sugg[k]))
y += x
return y
#app.route("/getrecomm",methods=['GET','POST'])
def getrecomm():
restname = request.args.get('restname', type=str)
number = request.args.get('number', type=int)
i = getBusIndex(restname, names)
return make_response(jsonify(result=(print_most_similar(rating, names, i, number))),200)
Currently, the results print like this:
REC 1: Harbor House Cafe & Lounge\nREC 2: Starbucks\nREC 3: McDonald's\nREC 4: Taco Bell\nREC 5: Panda Express\n
I would like them to print like this:
REC 1: Harbor House Cafe & Lounge
REC 2: Starbucks
REC 3: McDonald's
REC 4: Taco Bell
REC 5: Panda Express
I'm using python 3, fyi. Any suggestions would be super appreciated!

Summary
Answer: <br>
Alternative: JSONView Chrome Extension
The only one that give me good results was <br>:
Example
from flask import Flask, jsonify
app = Flask(__name__)
tasks = [
{
'<br>id': 1,
'title': u'Buy groceries',
'description': u'Milk, Cheese, Pizza, Fruit, Tylenol',
'done': False
},
{
'<br>id': 2,
'title': u'Learn Python',
'description': u'Need to find a good Python tutorial on the web',
'done': False
}
]
#app.route('/todo/api/v1.0/tasks', methods=['GET'])
def get_tasks():
return jsonify({'tasks': tasks})
if __name__ == '__main__':
app.run(debug=True)
In your browser the <br> character will be rendered as html and reproduce a new line.
Result:
"creates" new lines in json
Jsonify can't help you because it takes the values (integer,boolean,float, etc) as a string and avoid special characters like \n, \t, etc
Finally, if you just want a fancy way to visualize json files in your browser, you could use JSONView, is a Chrome extension that render Json files in a more understandable way, like this.
rendering with JSONView

Finally I have found the solutions.
It seems like that jsonify() function doesn't apply the "new lines" situation.
You can use Response()
from flask import Flask, Response
statement = """
try
try
try
"""
#app.route('/**/api/v1/**', methods=['GET'])
def get_statement():
return Response(statement, mimetype='text/plain')
I'm also new learner for flask, Response()function works on my app.

Related

Python flask server to retrieve certain records

I have this following python code for a Flask server. I am trying to have this part of the code list all my vehicles that match the horsepower that I put in through my browser. I want it to return all the car names that match the horsepower, but what I have doesn't seem to be working? It returns nothing. I know the issue is somewhere in the "for" statement, but I don't know how to fix it.
This is my first time doing something like this and I've been trying multiple things for hours. I can't figure it out. Could you please help?
from flask import Flask
from flask import request
import os, json
app = Flask(__name__, static_folder='flask')
#app.route('/HORSEPOWER')
def horsepower():
horsepower = request.args.get('horsepower')
message = "<h3>HORSEPOWER "+str(horsepower)+"</h3>"
path = os.getcwd() + "/data/vehicles.json"
with open(path) as f:
data = json.load(f)
for record in data:
horsepower=int(record["Horsepower"])
if horsepower == record:
car=record["Car"]
return message
The following example should meet your expectations.
from flask import Flask
from flask import request
import os, json
app = Flask(__name__)
#app.route('/horsepower')
def horsepower():
# The type of the URL parameters are automatically converted to integer.
horsepower = request.args.get('horsepower', type=int)
# Read the file which is located in the data folder relative to the
# application root directory.
path = os.path.join(app.root_path, 'data', 'vehicles.json')
with open(path) as f:
data = json.load(f)
# A list of names of the data sets is created,
# the performance of which corresponds to the parameter passed.
cars = [record['Car'] for record in data if horsepower == int(record["Horsepower"])]
# The result is then output separated by commas.
return f'''
<h3>HORSEPOWER {horsepower}</h3>
<p>{','.join(cars)}<p>
'''
There are many different ways of writing the loop. I used a short variant in the example. In more detail, you can use these as well.
cars = []
for record in data:
if horsepower == int(record['Horsepower']):
cars.append(record['Car'])
As a tip:
Pay attention to when you overwrite the value of a variable by using the same name.

Cloud Firestore - how retrieve document infos of nested subcollection?

The firestore db has a structure like this:
collection: users
documents with id an user_id
each document has a sub-collection: games
each sub-collection has documents with id a game_id
My problem is that I can't loop over the first collection (---> for user in ref_users:) even my firestore db is already full with data organized like I said. Can someone help me understanding how can I retrieve the infos of these documents? Thanks a lot.
from flask import Flask, render_template
from google.cloud import firestore
db = firestore.Client()
#app.route('/', methods=['GET'])
def index():
ref_users = db.collection(u'users').get()
games = []
for user in ref_users:
print(f'{user.id} => {user.to_dict()}')
ref_game = db.collection(u'users').document(f'{user.id}').collection(u'games').get()
for rg in ref_game:
print(f'{rg.id} => {rg.to_dict()}')
tmp = rg.to_dict()
tmp['game_id'] = rg.id
tmp['user_id'] = user.id
games.append(tmp)
return render_template('game_list.html', title='Game list', games=games)
Implemented this code on my side with some minor changes and its working fine. So I think that you are maybe searching for solution to decrease computational complexity.
I think that collection_group might be helpful. Please check general documentation and Python reference.
I have created code for the same result as the sample (just index part). It has one loop less:
def index():
games = []
ref_game = db.collection_group(u'games').get()
for rg in ref_game:
print(f'{rg.id} => {rg.to_dict()}')
tmp = rg.to_dict()
tmp['game_id'] = rg.id
tmp['user_id'] = rg.reference.parent.parent.id
games.append(tmp)
return str(games)
I would use more sophisticated name for this subcollection like userGames or something. This is because of the fact that collection_group works on every collection with this name in whole database. If your system with grow, there is a chance that you will use the same name games in some other path not related to this logic. Than it will be included to this collection_group and may cause unexpected issues.

Starting python if function with an empty value possibility

Automated stock bot in development here.
I'm trying to start an "if" function when an empty list value is returned as the argument, and end the script if a text (string?) value is returned. The reason for this is because I don't want to execute the if function if I currently have a trade open, only when I have no trades open. As far as I know the only modules from my broker's API(Oanda) useful to execute this task is one that outputs [] when I don't have a trade open. This was retrieved from the following list {'positions': [], 'lastTransactionID': '4765'} Part of me thinks what I'm trying to do is impossible, based on the research I've done, but I'm hoping someone has an idea. I put double asterisks around the important part of the script.
from flask import Flask, request, abort
import oandapyV20
import oandapyV20.endpoints.positions as positions
from exampleauth import exampleAuth
# Create Flask object called app.
app = Flask(__name__)
# Create root to easily let us know its on/working.
#app.route('/')
def root():
return 'online'
#app.route('/webhook', methods=['POST'])
def webhook():
if request.method == 'POST':
accountID, access_token = exampleAuth()
api = oandapyV20.API(access_token=access_token)
client=oandapyV20.API(access_token)
r=positions.OpenPositions(accountID)
x=client.request(r)
**if x['positions']=='[]': #if empty execute if function, if not return 'okay'
data = parse_webhook(request.get_data(as_text=True))
sell=data['side']
if data['side']=='sellEURAUD':
exec(open("marketTPSLEURAUDv2sell.py").read())
elif data['side']=='buyEURAUD':
exec(open("marketTPSLEURAUDv2buy.py").read())
else:
return 'okay'**
if __name__ == '__main__':
app.run()
Just remove the qutos from empty list.
Should be like this-
if x['positions']==[]:

Run pythod code with Django and produce output on web

I know this could be a repeated question for many of you but I have not been able to find a proper answer for this yet. I am a beginner to Django and Python. I have a python code which runs and produce output on cli at present but I want the same program to run its output on web.
I read that for web django is best suitable framework and for this purpose I started to study django. I see in every tutorial people have discussed apps, views urls etc but not seen an example which integrate a python code with django.
All I am looking for to understand how can I integrate my python script with Django and where do I place my code in Django project or app. Should I import it within views? if yes, then how to present my output to web.
Here is the sample code I am running, it basically opens two files and run some regex to extract the desired information.
import re
def vipPoolFileOpen(): # function opens vip and pool config file and store them to vip_config and pool_config variables
with open("pool_config.txt",'rb') as pool_config:
pool_config = pool_config.read()
pool_config = pool_config.split('ltm')
with open("vip_config.txt",'rb') as vip_config:
vip_config = vip_config.read()
vip_config = vip_config.split('ltm')
return vip_config,pool_config
def findWidth(vip_config): # function to find the maximum length of vip in entire file, this will be used to adjust column space
colWidth=0
for item in vip_config:
i=0
if colWidth<len(item):
while i<len(vip_config)-1:
if len(item)>=len(vip_config[i+1]):
colWidth=len(item)
i=i+1
else:
i+=1
continue
return colWidth
def regexFunction():
vip_config, pool_config = vipPoolFileOpen()
findWidth(vip_config)
for vip in vip_config:
regVip = re.compile(r'pool (.+)\r')
poolByVip = regVip.findall(vip) # poolByVip holds pool name from the vip_config file
for poolblock in pool_config:
regPool = re.compile(r'pool (.+) {')
poolByConfig = regPool.findall(poolblock)
if poolByVip == poolByConfig:
print vip + poolblock
break
elif poolByVip == ['none']:
print vip
break
else:
continue
Yes, you should present your output to the web via view. You need to write a view function (or a class view) in views.py and provide an url where you want to have it in urls.py
If you rewrite your function to return desired result instead of printing it, tou can do the following:
write this in views.py
from django.http import HttpResponse
from wherever_you_have_it import regexFunction
def bar(request):
result = regexFunction() # result should be a string
return HttpResponse(result)
and in urls.py:
from .views import bar
urlpatterns = [
url(r'^foo$', bar),
]
Providing of course you have created your Django app at the first place.
Your result should be displayed as plain text on address localhost:8000/foo - but you need to:
python menage.py runserver
In your terminal first
And of course feel free to look at:
https://github.com/Ergaro/CheckMyChords
to see how a simple django app looks like

Django AngularJS JSONResponse view in rendering json output

i am developing one of my site with the python django where i have been using angularjs in one of my page where i have given the user option to search (specific request). Here is my model..
class Request(models.Model):
description = models.TextField(blank=True,null=True)
category = models.ForeignKey(Category)
sub_category = models.ForeignKey(SubCategory)
In my views I am returning through the following code:
def some(code, x):
exec code
return x
def search_request(request):
page = request.GET.get('page')
term = request.GET.get('term')
i = 0
terms = "x = Request.objects.filter("
for t in term.split(" "):
i=i+1
if(len(term.split(" "))>i):
terms = terms +"Q(name__icontains='"+t+"')|"
else:
terms = terms +"Q(name__icontains='"+t+"'))"
junk = compile(terms,'<string>', 'exec')
spit = Request.objects.filter(name__icontains=term)
requests = some(junk,spit)
output = HttpResponse()
output['values']=[{'requests':r,'category':r.category,'subcategory':r.sub_category} for r in requests]
return JSONResponse(output['values'])
In my HTML code when I return using AngularJS:
$scope.search = function(){
$scope.results = $http.get("{% url 'search-requests-show' %}?term="+$scope.term).then(
function(result){
return result.data;
}
);
}
The result on the HTML Output comes as in {[{results}]}:
"[{'category': <Category: The New Category>, 'requests': <Request: Need a Table>, 'subcategory': <SubCategory: Testsdfsdfsad>}]"
The problem is that I am not being able to access using results.category because the output is in "string", so the ng-repeat="result in results" brings the result as
[ { ' c a .....
I am probably doing something wrong in view. If anybody has any suggestion then please answer.
JSONResponse is probably using standard python json encoder, which doesn't really encode the object for you, instead it outputs a string representation (repr) of it, hence the <Category: The New Category> output.
You might need to use some external serializer class to handle django objects, like:
http://web.archive.org/web/20120414135953/http://www.traddicts.org/webdevelopment/flexible-and-simple-json-serialization-for-django
If not, you should then normalize object into simple python types inside the view (dict, list, string.., the kind that json module has no problem encoding). So instead doing:
'category':r.category
you could do:
'category': {'name': r.category.name}
Also as a sidenote: using exec is super bad idea. Don't use it in production!
You should return json strings for Angular:
import json
def resource_view(request):
# something to do here
return HttpResponse(json.dumps(your_dictionary))
for better usage i recommend djangorestframework.
Off Topic:
$http.get("{% url 'search-requests-show' %}?term="+$scope.term);
you can pass 'param' object:
$http.get("{% url 'search-requests-show' %}", {param : {term:$scope.term}});

Categories

Resources