subprocess.Popen line in flask app not running on pythonanywhere while it work on local machine.. any idea why or how to catch error? - flask

subprocess.Popen line (40) in flask app not running on pythonanywhere while it works on local machine.. tried different variation of the subprocess line but no luck. no error shown in error logs in pythonanywhere.
any idea why there is a difference to functionality on pythonanywhere vs local machine and how to fix or how to catch error of subprocess?
enter image description here
from flask import Flask, render_template, request
from flask_mysqldb import MySQL
import yaml
from subprocess import Popen, PIPE
from threading import Thread
import time
import subprocess
app = Flask(__name__)
# config db
db = yaml.full_load(open('db.yaml'))
app.config['MYSQL_HOST'] = 'xxx'
app.config["MYSQL_USER"] = "xxx"
app.config["MYSQL_PASSWORD"] = "xxx"
app.config["MYSQL_DB"] = "xxx"
mysql = MySQL(app)
#app.route("/", methods=["GET", "POST"])
def index():
if request.method =="POST":
#fetch form data
userDetails=request.form
title=userDetails["title"]
location=userDetails["location"]
radius=userDetails["radius"]
email=userDetails["email"]
cur = mysql.connection.cursor()
cur.execute("INSERT INTO requests(title, location, radius, email) VALUES(%s, %s, %s, %s)", (title, location, radius, email))
mysql.connection.commit()
cur.close()
subprocess.Popen(['python', 'file.py'])
return render_template('donenew.html')
return render_template("indexnew.html")
if __name__ == "__main__":
app.run(debug=True)

Related

Integrate flask-sqlalchemy into project

I am new comer of flask api. I am doing a flask restful api project which purpose is to search stores by store name that is kept in existing database online.
Now is is connect to database using psycopg2.
I would like to improve it by using flask-sqlalchemy. I have searched on the web and the solution seems to use Automap, that I learned from the tutorial. The problem I am facing now is how to integrate those codes into my existing project, like where should I put the settings like automap_base() into my existing codes. Here is my current file structure:
app.py
∟ models
∟ family_mart.py
∟ resources
∟ family_mart.py
app.py:
from flask import Flask
from flask_restful import Api
from resources.family_mart import FamilyMart
app = Flask(__name__)
app.secret_key = 'apple'
api = Api(app)
api.add_resource(FamilyMart, '/familymart/<string:name>')
if __name__ == '__main__':
app.run(port=5000, debug=True)
family_mart.py in models folder:
import psycopg2
from config import config
class FamilyMartModel:
#classmethod
def find_by_name(cls, name):
conn = None
try:
params = config()
conn = psycopg2.connect(**params)
cur = conn.cursor()
query = f"""
SELECT extract_date
, store_name
, address
FROM cnvnt_str_fm
WHERE store_name = '{name}'
"""
cur.execute(query)
rows = cur.fetchall()
cur.close()
if rows:
result = {'store':[]}
for row in rows:
append_dict = {'extract_date':row[0].strftime('%Y-%m-%d'),
'store_name':row[1],
'address':row[2]}
result['store'].append(append_dict)
return result
except (Exception, psycopg2.DatabaseError) as error:
print(error)
finally:
if conn is not None:
conn.close()
print('Database connection closed.')
family_mart.py in resources folder:
from flask_restful import Resource
from models.family_mart import FamilyMartModel
class FamilyMart(Resource):
def get(self, name):
item = FamilyMartModel.find_by_name(name)
if item:
return item
return {'message':'Store not found.'}, 404
After study the documentation, I restructured my project and integrate with sqlalchemy successfully. I removed model folder and added db.py to configure the existing database, here is the detail :
New file structure:
app.py
∟ resources
∟ family_mart.py
db.py
app.py:
from flask import Flask
from flask_restful import Api
from config import config
from db import db
from resources.family_mart import FamilyMart
params = config()
DB_FULL_URL = f"postgresql+psycopg2://{params['user']}:{params['password']}#{params['host']}/{params['database']}"
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = DB_FULL_URL
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.secret_key = 'apple'
api = Api(app)
api.add_resource(FamilyMart, '/familymart/<string:name>')
if __name__ == '__main__':
db.init_app(app)
app.run(port=5000, debug=True)
db.py:
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import MetaData
from sqlalchemy import Table, Column, Integer, String, DateTime
db = SQLAlchemy()
metadata_obj = MetaData()
fm_table = Table('cnvnt_str_fm', metadata_obj,
Column('extract_date', String),
Column('store_name', String),
Column('address', String)
)
family_mart.py:
from flask_restful import Resource
from db import db
from db import fm_table
class FamilyMart(Resource):
def get(self, name):
results = db.session.query(fm_table).filter_by(store_name=name).\
order_by(fm_table.c.extract_date.desc()).limit(3)
output = {'store':[]}
for row in results:
extract_date = str(row[0])
store_name = row[1]
address = row[2]
output['store'].append({'extract_date':extract_date,
'store_name':store_name,
'address':address})
return output

Telebot not responding to requests with FLask server

I am trying to deploy my telegram bot to Heroku using Flask. ALthough I followed the tutorials and set up everything the same I am not getting any result and my bot is not responding.
import requests
import pandas as pd
import telebot
from telebot import types
import random
import os
from flask import Flask, request
from requests.models import MissingSchema
URL_HEROKU = f"some_url"
TOKEN = os.environ['TOKEN']
bot = telebot.TeleBot(TOKEN, parse_mode=None)
app = Flask(__name__)
#bot.message_handler(commands=['start'])
def start(message):
#Init keyboard markup
msg = ''' Hello, how are you?'''
bot.reply_to(message, msg)
#bot.message_handler(commands=['random'])
#bot.message_handler(regexp=r'random')
def send_some(message):
bot.send_message(message.chat.id, text='Hello')
#app.route('/' + TOKEN, methods=['GET'])
def getMessage():
bot.process_new_updates([telebot.types.Update.de_json(request.stream.read().decode("utf-8"))])
return "!", 200
#app.route("/")
def webhook():
bot.remove_webhook()
bot.set_webhook(url= URL_HEROKU + TOKEN)
return "!", 200
if __name__ == "__main__":
app.run(host="0.0.0.0", port=int(os.environ.get('PORT', 5000)))
My Procfile is:
web: python telebreed.py
and my requirements.txt:
Flask==2.0.2
gunicorn==20.1.0
pandas==1.2.2
pyTelegramBotAPI==4.6.0
requests==2.26.0
do you see any mistake ? When I open my app in Heroku I only see "!" which is the character defined in getMessage() method.

Unable to Access Flask App URL within Google Colab getting site not available

I have created a Flask prediction app (within Google Colab) and when I am trying to run it post adding all the dependencies within the colab environment I am getting the url but when I click on it it show site cannot be reached.
I have the Procfile, the pickled model and the requirements text file but for some reason its not working. Also, I tried deploying this app using Heroku and it met the same fate where I got the app error.
For more context please visit my github repo.
Any help or guidance will be highly appreciated.
from flask import Flask, url_for, redirect, render_template, jsonify
from pycaret.classification import*
import pandas as pd
import numpy as np
import pickle
app = Flask(__name__)
model = load_model('Final RF Model 23JUL2021')
cols = ['AHT','NTT','Sentiment','Complaints','Repeats']
#app.route('/')
def home():
return render_template("home.html")
#app.route('/predict',methods=['POST'])
def predict():
int_features = [x for x in request.form.values()]
final = np.array(int_features)
data_unseen = pd.DataFrame([finak], columns = cols)
prediction = predict_model(model, data=data_unseen, round=0)
prediction = int(prediction.Label[0])
return render_template('home.html',pred='Predicted Maturiy Level is{}'.format(prediction))
#app.route('/predict_api',methods=['POST'])
def predict_api():
data = request.get_json(force=True)
data_unseen = pd.DataFrame([data])
prediction = predict_model(model, data=data_unseen)
output = prediction.Label[0]
return jsonify(output)
if __name__ == '__main__':
app.run(debug=True)
You cannot run flask app same as in your machine. You need to use flask-ngrok.
!pip install flask-ngrok
from flask_ngrok import run_with_ngrok
[...]
app = Flask(__name__)
run_with_ngrok(app)
[...]
app.run()
You can't use debug=True parameter in ngrok.

Python: Erratic joblib behaviour on Flask

I am trying to deploy a machine learning model on AWS EC2 instance using Flask. These are sklearn's fitted Random Forest models that are pickled using joblib. When I host Flask on localhost and load them into memory everything runs smoothly. However, when I deploy it on the apache2 server using mod_wsgi, joblib works sometimes(i.e. the models are loaded using joblib sometimes) and the other times the server just hangs. There is no error in logs. Any ideas would be appreciated.
Here is the relevant code that I am using:
# In[49]:
from flask import Flask, jsonify, request, render_template
from datetime import datetime
from sklearn.externals import joblib
import pickle as pkl
import os
# In[50]:
app = Flask(__name__, template_folder="/home/ubuntu/flaskapp/")
# In[51]:
log = lambda msg: app.logger.info(msg, extra={'worker_id': "request.uuid" })
# Logger
import logging
handler = logging.FileHandler('/home/ubuntu/app.log')
handler.setLevel(logging.ERROR)
app.logger.addHandler(handler)
# In[52]:
#app.route('/')
def host_template():
return render_template('Static_GUI.html')
# In[53]:
def load_models(path):
model_arr = [0]*len(os.listdir(path))
for filename in os.listdir(path):
f = open(path+"/"+filename, 'rb')
model_arr[int(filename[2:])] = joblib.load(f)
print("Classifier ", filename[2:], " added.")
f.close()
return model_arr
# In[54]:
partition_limit = 30
# In[55]:
print("Dictionaries being loaded.")
dict_file_path = "/home/ubuntu/Dictionaries/VARR"
dictionaries = pkl.load(open(dict_file_path, "rb"))
print("Dictionaries Loaded.")
# In[56]:
print("Begin loading classifiers.")
model_path = "/home/ubuntu/RF_Models/"
classifier_arr = load_models(model_path)
print("Classifiers Loaded.")
if __name__ == '__main__':
log("/home/ubuntu/print.log")
print("Starting API")
app.run(debug=True)
I was stuck with this for quite sometime. Posting the answer in case someone runs into this problem. Using print statements and looking at logs I narrowed the problem down to joblib.load statement. I found this awesome blog: http://blog.rtwilson.com/how-to-fix-flask-wsgi-webapp-hanging-when-importing-a-module-such-as-numpy-or-matplotlib
The idea of using a global process group fixed the problem. That forced the use of main interpreter just as the top comment on that blog page mentions.

how to use db instance in flask-apscheduler's jobs function

When I used flask-apscheduler(not apscheduler), I have some problems in my flask web project. Especially when I used db(flask-sqlalchemy) objects. The problem may be:
JOBS = [
{
'id': 'job1',
'func': 'app.monitor.views:test',
'args': (),
'trigger': 'interval',
'seconds': 2
}
]
./app/init.py:
from flask import Flask
from flask.ext.bootstrap import Bootstrap
from flask.ext.mail import Mail
from flask.ext.moment import Moment
from flask.ext.sqlalchemy import SQLAlchemy
from flask.ext.login import LoginManager
from flask.ext.pagedown import PageDown
from flask_apscheduler import APScheduler
from celery import Celery
# from apscheduler.schedulers.blocking import BlockingScheduler
from config import config,Config
bootstrap = Bootstrap()
mail = Mail()
moment = Moment()
db = SQLAlchemy()
pagedown = PageDown()
celery = Celery(__name__, broker=Config.CELERY_BROKER_URL)
# https://pypi.python.org/pypi/Flask-APScheduler
scheduler = APScheduler()
login_manager = LoginManager()
login_manager.session_protection = 'strong'
login_manager.login_view = 'auth.login'
def create_app(config_name):
app = Flask(__name__)
app.config.from_object(config[config_name])
config[config_name].init_app(app)
bootstrap.init_app(app)
mail.init_app(app)
moment.init_app(app)
db.init_app(app)
login_manager.init_app(app)
pagedown.init_app(app)
scheduler.init_app(app)
celery.conf.update(app.config)
if not app.debug and not app.testing and not app.config['SSL_DISABLE']:
from flask.ext.sslify import SSLify
sslify = SSLify(app)
from .monitor import monitor as monitor_1_0_blueprint
from .laser import laser as laser_1_0_blueprint
app.register_blueprint(monitor_blueprint,url_prefix='/monitor/api')
app.register_blueprint(laser_1_0_blueprint,url_prefix='/laser/api/v1.0')
return app
Error 1:db is : Error 2:db is :No handlers
could be found for logger "apscheduler.executors.default" Error 3:db
is : raise RuntimeError('working outside of application context')
RuntimeError: working outside of application context
The key to the problem is to get the db and app objects in flask-apscheduler jobs function(views.py):
from app import scheduler
def test():
#to Solve the log error problem
import logging
log = logging.getLogger('apscheduler.executors.default')
log.setLevel(logging.INFO) # DEBUG
fmt = logging.Formatter('%(levelname)s:%(name)s:%(message)s')
h = logging.StreamHandler()
h.setFormatter(fmt)
log.addHandler(h)
#get the app object
app = scheduler.app
#get the db object and use it
with app.app_context():
print '........................',db
from app import scheduler#
def test():
#to Solve the log error problem
import logging
log = logging.getLogger('apscheduler.executors.default')
log.setLevel(logging.INFO) # DEBUG
fmt = logging.Formatter('%(levelname)s:%(name)s:%(message)s')
h = logging.StreamHandler()
h.setFormatter(fmt)
log.addHandler(h)
#get the app object
app = scheduler.app
#get the db object and use it
with app.app_context():
print '........................',db
def test():
#to Solve the log error problem
import logging
log = logging.getLogger('apscheduler.executors.default')
log.setLevel(logging.INFO) # DEBUG
fmt = logging.Formatter('%(levelname)s:%(name)s:%(message)s')
h = logging.StreamHandler()
h.setFormatter(fmt)
log.addHandler(h)
#get the app object
app = scheduler.app
#get the db object and use it
with app.app_context():
print '........................',db #the right db object