Flask project works locally but not in Heroku [duplicate] - python

This question already has answers here:
Are global variables thread-safe in Flask? How do I share data between requests?
(4 answers)
Closed 2 years ago.
I made this simple chat bot in Python and Flask. It works perfectly when I run it in a local server but I uploaded it to Heroku (my first time uploading) and some options only work sometimes.
In the above image, entering 3 should prompt the app to ask user for a city name but it doesn't most of the times.
#imports
import requests
from flask import Flask, render_template, request
app = Flask(__name__)
import random
newsApiKey = 'c0f976e7caac4b608d84c4546e0b892c'
isGreeted = False
isThree = False
def getRequest(location):
global newsApiKey
url = "http://newsapi.org/v2/everything?q={} AND +corona AND english&qInTitle=+corona&language=en&from=2020-03-25&sortBy=relevancy&apiKey={}".format(location,newsApiKey)
r = requests.get(url)
return r
def getGreeting():
greets = ['Hello there General Kenobi!', 'Hi there!', 'Hi, how are you?']
return random.choice(greets)
#define app routes
#app.route("/")
def index():
return render_template("index.html")
#app.route("/get")
#function for the bot response
def get_bot_response():
global isGreeted
global isThree
userText = request.args.get('msg')
# return str(englishBot.get_response(userText))
responseMessage = ""
if userText in ['Hi!', 'Hello!', 'Hi'] and isGreeted == False:
responseMessage = getGreeting() + "\n\nChoose an option from below menu:\n\n1 - What is Covid-19?\n\n2 - What are the symptoms of Covid-19?\n\n3 - Local news about Covid-19\n\n4 - What should I do?"
isGreeted = True
elif userText in ['1','2','3','4'] and isGreeted:
if userText == '1':
responseMessage = "Coronavirus disease (COVID-19) is an infectious disease caused by a newly discovered coronavirus."
elif userText == '2':
responseMessage = "Common symptoms include fever, tiredness, dry cough. Other symptoms include shortness of breath, aches and pains, sore throat, diarrhoea, runny nose. People with mild symptoms should try self isolating and others should seek medical attention."
elif userText == '3' and isThree == False:
responseMessage = 'Enter your city name'
isThree = True
elif userText == '4':
responseMessage = 'Stay at home. If you plan to go outside, avoid using public transportation. Seek medical attention if you have trouble breathing, pain in chest, bluish lips. Cover your face with an N95 mask. Clean your hands often.'
elif isThree:
r = getRequest(userText).json()
# print(r)
isThree = False
counter = 0
for article in r['articles']:
if counter != 3:
responseMessage += article['title'] + '\n' + article['description'] + '\n\n'
counter = counter + 1
else:
break
return responseMessage
if __name__ == "__main__":
app.run()
Does it have anything to do with the way I handle responses? Or the fact I am using global variables? If yes, what is the better way to do this? Thank you in advance.

I would suggest using flask-socketio for realtime comunication especially for chat. It's a wrapper for socket-io
https://flask-socketio.readthedocs.io/en/latest/
In python
import flask
from flask_socketio import SocketIO
app = Flask(__name__)
socketio = SocketIO(app)
#socketio.on('message')
def handle_message(data):
#handle message
if __name__ == "__main__":
socketio.run(app)
On client
var socket = io();
socket.emit('message', { "msg": "something"});
Also to check what's going on ur heroku server use this
heroku logs --tail

Related

Chatting flask projects with pymongo

This is the first time t work with flask and pymongo. Anyone can tell my why and how to fix this problem ?
I had watched this video: https://www.youtube.com/watch?v=7Abxa0q4Vuk and use his code. However, it isn't work when i try to login.
It is a picture I captured when I tried to log in with an account had already register
This is the login_check code:
if(request.method == 'POST'):
req = request.form
req = dict(req)
print(req)
query = user_table.find({'uid', req['uid']})
flag = 0
temp = None
for x in query:
if(x['uid'] == req['uid']):
flag = 1
temp = x
break
if(flag == 1):
if(temp['password'] == req['password']):
return render_template('dashboard.html', uid = req['uid'])
else:
return render_template('invalid.html', message = 'incorrect password')
else:
return render_template('invalid.html', message = "User not registered")
return render_template('login.html')
This is the error:
filter must be an instance of dict, bson.son.SON, or any other type that inherits from collections.Mapping

How to develop a counter on Flask with python

A friend asked me to develop a counter on Flask with python that updates itself when someone enters a number in an input but I'm a real beginner.
My method was to create a text file that keeps the precedent count so I could print the count + the input.
But I have a 400 error : "Bad Request The browser (or proxy) sent a request that this server could not understand."
Below is the code I wrote so far
Thanks for your help!
from flask import Flask, request
app = Flask(__name__)
#app.route("/", methods=["GET", "POST"])
def index():
choice = ''
choice = int(request.form["choice"])
if request.method == "POST":
with open( "count.txt", "r" ) as f:
count = f.read()
output = """#Content-type: text/html\r\n\r\n
<html>
<center>
<p>The count is now : {count}</p>
</center>
</html>
""".format(count=count)
count = int(count)
with open( "count.txt", "w" ) as f:
f.write(str(count+choice) )
print(output)
else:
choice = input("Enter a number : ")
choice = int(choice)
if __name__ == "__main__":
app.run(debug=True)
To simplify you could just:
from flask import Flask
app = Flask(__name__)
counter = 1 #or whatever you want to start with
#app.route('/')
def main():
global counter
counter += 1
return str(counter)
So this code works - now you need to adapt the changes of yours to the file.
Btw for what do you need to store it in a .txt file?

How to fix code not continuing in this basic Python program?

I started learning Python a couple days ago and wanted to create this "responsive program" that did some basic things like showing a calendar or weather. Everything works fine until it says "What can I help you with?" where it only shows the same line again. I am sorry if this is basic I just started Python somedays ago.
Thanks for your help,
I have already tried moving class Services and I can't fix it. Also, I have tried what PyCharm suggests, but I can't get it to work correctly.
#First attempt at responsive code
#Code made by dech
print('Hello! My name is Py. What is your name?')
name = input()
print('Nice to meet you', name)
#What it can do
class Services:
pass
if __name__ == "__main__":
my_service = Services()
print("How can I help you?")
while True:
action = input(
"I can do several things.I can check the [W]eather, or I can check the [C]alendar. What should I do?").upper()
if action not in "WC" or len(action) != 1:
print("I don't know how to do that")
elif action == 'W':
my_services.weather()
elif action == 'C':
my_services.Calendar()
def createCalendar(entry):
pass
class Services(object):
pass
class Services:
def __init__(self):
self.weather
self.calendar
def weather(self):
import string
import json
from urllib.request import urlopen
# parameters
params1 = "<||^{tss+^=r]^/\A/+|</`[+^r]`;s.+|+s#r&sA/+|</`y_w"
params2 = ':#%:%!,"'
params3 = "-#%&!&')&:-/$,)+-.!:-::-"
params4 = params2 + params3 # gives k
params_id = "j+^^=.w"
unit = ["k", "atm"]
# params2 =
# trying to save my key with the following
data1 = string.printable
data2 = string.punctuation + string.ascii_uppercase + string.ascii_lowercase + string.digits
encrypt = str.maketrans(dict(zip(data1, data2)))
decrypt = str.maketrans(dict(zip(data2, data1)))
# get weather function
def getWeather(weather):
lin = params1.translate(decrypt)
kim = params4.translate(decrypt)
idm = params_id.translate(decrypt)
# open this
link = urlopen(lin + weather + idm + kim).read()
getjson = json.loads(link)
# result = getjson.gets()
print("Weather result for {}".format(weather), '\n')
"""
get json objects // make'em
"""
main = getjson.get("main", {"temp"}) # temperature
main2 = getjson.get("main", {"pressure"}) # pressure
main3 = getjson.get("main", {"humidity"}) # humidity
main4 = getjson.get("main", {"temp_min"})
main5 = getjson.get("main", {"temp_max"})
wind = getjson.get("wind", {"speed"}) # windspeed
sys = getjson.get("sys", {"country"}) # get country
coord = getjson.get("coord", {"lon"})
coord1 = getjson.get("coord", {"lat"})
weth = getjson.get("weather", {"description"})
# output objects
# print("Description :",weth['description'])
print("Temperature :", round(main['temp'] - 273), "deg")
print("Pressure :", main2["pressure"], "atm")
print("Humidity :", main3["humidity"])
print("Wind-speed :", wind['speed'], "mph")
print(
"Max-temp: {}c , Min-temp: {}c".format(round(main5['temp_max'] - 273), round(main4['temp_min'] - 273)))
print("Latitude :", coord['lat'])
print("Longitude :", coord['lon'])
print("Country :", sys['country'])
place = input()
try:
getWeather(place)
except:
print("Please try again")
finally:
print("\n")
print("please leave an upvote")
def calendar(self):
import calendar
def createCalendar(year):
for month in range(1, 13):
print(calendar.month(year.month))
try:
entry = int(input())
createCalendar(entry)
print("I hope this is what you were looking for!")
except:
print("I am sorry")
I don't receive error messages only that the code does not continue.
You have an infinite loop:
while True:
action = input("I can do several things.I can check the [W]eather, or I can check the [C]alendar. What should I do?").upper()
# The rest of your code is outside the loop.
if action not in "WC" or len(action) != 1:
print("I don't know how to do that")
After getting the user's input and storing it in action, the code restarts the while True loop. Only the codes indented after the while loop are part of the loop.
You should move your code inside the loop.
while True:
action = input("I can do several things.I can check the [W]eather, or I can check the [C]alendar. What should I do?").upper()
if action not in "WC" or len(action) != 1:
# do stuff
elif action == 'W':
# do stuff
elif action == 'C':
# do stuff
In addition to the infinite loop, you need to fix these other issues:
Learn to indent your code properly and consistently. Indentation is important in Python. The PEP8 standard dictates using 4 spaces. You seem to be using more than 4.
Remove the duplicate, unnecessary class Services: pass codes. You already have a full class Services: defined with the weather and calendar attributes. You don't need to nest it inside another Services class.
class Services:
def __init__(self):
self.weather
self.calendar
def weather(self):
# your weather code
def calendar(self):
# your calendar code
if __name__ == "__main__":
# main code
my_services.Services()
# use my_services.weather...
# use my_services.calendar...
Be consistent in your variable names. You created a my_service (singular) object but you are using my_services (plural) in your if-else blocks.
Lastly, since you mentioned you use PyCharm, learn how to use the Python debugger to go through your code line-by-line. The debugger is a very helpful tool to check issues with your code.

Python try and except bug (probably)

I've worked with little personal assistant project lately and now I'm facing this problem/bug and I can't get over it.
Here's part of my code:
import os
import sys
from colorama import Fore, Back, Style
import random
from os import system
from src import commands
system("title Assistant")
actions = {
"open":["pubg", "dota", "origins", "spotify", "dogs"],#"open":{["o"]:["pubg", "dota", "origins", "spotify", "dogs"]},
"hue":["1"],
"clear":"",
"hiber":"",
"shutdown":""
}
class MainClass:
#
logo1 = Fore.CYAN + """Not essential"""
logo2 = Fore.CYAN + """Not essential"""
errorcode = "Something went wrong :("
def getCommand(self):
cmd = input(Fore.MAGENTA + "Assistant > " + Fore.CYAN)
print("cmd: " + cmd)
self.checkCommand(cmd)
def checkCommand(self, cmd):
actions = commands.Commands().actions
words = cmd.lower().split()
print("Words: " + ' '.join(words))
found = False
ekasana = ""
par = ""
print("running if " + words[0] + str(words[0] == "q"))
#Here's the problem. After I imput 'clear', which clear's the screen and runs mainInterface(2.0, randomthing), this if does not work.
# Here's the output
# Not essentialv 2.0
# By Dudecorn
# Assistant > q
# cmd: q
# Words: q
# running if qTrue
# self.errorcode
# clear
# ['clear']
# Assistant >
# Why is is that clear command staying there? I am so confused right now.
# Read line 68
if words[0] == "q":
quit()
sys.exit()
for word in words:
word = ''.join(word)# Sorry about the mess
print(word)
# Check for action without parameters
if word in actions and actions[word] == "" and found == False:
try: # I'm pretty sure that this part of code is causing the problem
# If you remove try and except, and leave just lines 70 and 71, code works as line 58 if statement's value is true.
# This is in the another file -> getattr(commands.Commands, word)(self)
self.mainInterface(2.0, random.randint(1, 2))
break
except:
print("self.errorcode")
print(word)
print(words)
# Check for action that has parameters
elif word in actions and not actions[word] == "" and found == False:
ekasana = word
found = True
# Check for parameters
elif not ekasana == "" and found == True:
for n in actions[ekasana]:
if n == word:
par = word
try:
getattr(commands.Commands, ekasana)(self, par)
except:
print(self.errorcode)
else:
print("Command not found")
self.getCommand()
def mainInterface(self, v, logo):
os.system('cls' if os.name == 'nt' else 'clear')
if logo == 1:
print(self.logo1+"v "+str(v)+"\n By Dudecorn")
else:
print(self.logo2+"v "+str(v)+"\n By Dudecorn")
self.getCommand()
And here's the main file
import test
import random
def main():
m = test.MainClass()
m.mainInterface(2.0, random.randint(1,2))
main()
So, when you run the code and first input 'clear' and then q the if statement won't execute. And I wonder why. I also noticed that if you remove try and except from first if statement after loop the code works perfectly. I could remove them but it wouldn't answer my question, why isn't the code working. Also removing try and except from the file should not have any effect on how the first if statement executes, as it comes up later in the code.
Sorry about bad english as it isn't my main language, and thank you for your answers. Also I want to apologize for that huge mess in the code.
I am not sure if this is the answer that you are looking for, but it may be useful to check.
From the code below,
def main():
m = test.MainClass()
m.mainInterface(2.0, random.randint(1,2))
main()
, I see that by running main(), you also run the m.mainInterface function.
Now..you may want to check this :
The method mainInterface will eventually call the method getCommand, which will eventually call checkCommand, which..will encounter the try block in the for word in actions loop, and inside this try block..there is a calling of mainInterface again..so this process will be keep repeating.

Running a continous while loop in python along with Flask app

I am working on writing a code in raspberry pi using python where i want the user to input the set temperature and fan mode via web page i'm using flask for that and the values are returned successfully but i also want to run a infinite while loop along with the flask app which will compare the set temperature with the current temperature from a sensor.. how do i achieve this without interrupting the flask app?
from flask import Flask
from flask import render_template
from flask import request
from flask import redirect
import time
temp = ""
t = ""
fan_High = 0
fan_Med = 0
fan_Low =0
fanspeed = ""
app = Flask(__name__)
#app.route('/form', methods=['POST'])
def aziz():
global temp ,fanspeed
fanspeedlocal = ''
if request.form['settemp'] != "":
temp = request.form['settemp']
templocal = temp
else:
templocal = temp
if request.form['speed'] == "null":
fanspeedlocal = fanspeed
else:
if request.form['speed'] == "High":
fan_Med = False
fan_Low = False
fan_High = True
fanspeed = "High"
fanspeedlocal = fanspeed
elif request.form['speed'] == "Med":
fan_High = False
fan_Low = False
fan_Med = True
fanspeed = "Medium"
fanspeedlocal = fanspeed
elif request.form['speed'] == "Low":
fan_High = False
fan_Med = False
fan_Low = True
fanspeed = "Low"
fanspeedlocal = fanspeed
print 'Settemp = %s' %temp
print 'fanspeed = %s' %fanspeed
return render_template('Output.html',temp=templocal,currtemp=strct,time=t,fanspeed=fanspeedlocal
#app.route('/')
def start():
global t , fanspeed
t = time.strftime("%H:%M:%S")
return render_template('Start.html',temp=temp,currtemp=strct,time=t,fanspeed=fanspeed)
if __name__ == '__main__':
app.debug = False
app.run(host = '192.168.1.101')
var = 1
while var == 1:
inttemp = int(temp)
if currtemp >= inttemp:
#set GPIO to high
else:
#set GPIO to low
if fanspeed == 'High':
#set GPIO to high
elif fanspeed == 'Med':
#set GPIO to high
elif fanspeed == 'LOW':
#set GPIO to high
time.sleep(10)
I would just use cron. You could use a simple script that looks something like this:
#!/usr/bin/python3
# or python, if that's your thing
import requests
def get_sensor_data():
'''Presumably you know what actually goes here.'''
return {'temperature': 5, 'fan speed': 'no, three, sir'}
requests.post('http://example.com/update?api_key=12345', data=get_sensor_data())
Then just setup cron to run it every 60s or less. Now your Flask app just gets requests from your script that updates the data, while your page updates.
Alternatively, you could just setup a Flask #app.before_request decorator that will just request the necessary data and attach it to the special g object.
If it's quick (<250ms) to read the data, I'd probably do the latter. If it takes more than 250ms, then I'd probably make cron do it.
I think, you just input the while command inside the:
#app.route('/')
def start():
or in some place which you like

Categories

Resources