Python Flask app is not running on heroku servers - python-3.x

I am trying to deploy my flask app on heroku but it shows a runtime error on the heroku server, but when i test it on my end, AKA localhost, it seems to work fine
My Code:
import flask
from flask import request
from flask import jsonify
from GoogleNews import GoogleNews
from apscheduler.schedulers.background import BackgroundScheduler
import multiprocessing
googlenews = GoogleNews()
news_latest = []
googlenews.set_lang('en')
googlenews.set_period('1d')
googlenews.set_encode('utf-8')
def get_latest_news():
global news_latest
googlenews.get_news('TECHNOLOGY')
news_latest = googlenews.result()
my_scheduler = BackgroundScheduler()
my_scheduler.add_job(func=get_latest_news, trigger="interval", seconds=5)
my_scheduler.start()
app=flask.Flask(__name__)
#app.route('/', methods=["GET"])
def home():
return jsonify(news_latest[0: 3])
app.run()
requirements.txt:
gunicorn
GoogleNews
APScheduler
PROCFILE:
web: gunicorn app:appweb: gunicorn app:app
runtime.txt:
python-3.9.4
But the server seems to crash when you open it,
And what is remarkable is in the logs, Flask says it is running on a DEVELOPMENT server. It prints the location where it has started the app as 127.0.0.0.5000

I was able to overcome this problem, The right way of doing this is:
import flask
from flask import request
from flask import jsonify
from GoogleNews import GoogleNews
from apscheduler.schedulers.background import BackgroundScheduler
import multiprocessing
googlenews = GoogleNews()
news_latest = []
googlenews.set_lang('en')
googlenews.set_period('1d')
googlenews.set_encode('utf-8')
def get_latest_news():
global news_latest
googlenews.get_news('TECHNOLOGY')
news_latest = googlenews.result()
my_scheduler = BackgroundScheduler()
my_scheduler.add_job(func=get_latest_news, trigger="interval", seconds=5)
my_scheduler.start()
app=flask.Flask(__name__)
#app.route('/', methods=["GET"])
def home():
return jsonify(news_latest[0: 3])
The change was to remove app.run() since heroku servers will already be running your code, if you put the app.run() heroku will consider this as default code and will run that too, hence the interpretation process will stop at app.run() and will never complete the interpretation. Hence the app will crash with no return response.

On localhost is fine to use the default 5000 port but on Heroku you need to use the one provided by the platform in the $PORT env variable
server_port = int(os.environ.get("PORT", 5000))
app.run(debug=False, port=server_port, host='0.0.0.0')

Related

current_app application context in flask. Get working instance of flask

I am trying to setup simple flask application to perceive app_context() feature.
This is my code:
# config.py
UPDATE_PERIOD = 100.0
# init.py
from flask import Flask
import config
app = Flask(__name__)
app.config.from_object(config)
app.config['DEBUG'] = True
#app.route('/')
def hello_world():
return 'Hello, World!'
if __name__ == "__main__":
app.run()
# ex.py
from flask import current_app
from flask import Flask
app = Flask(__name__)
with app.app_context() as app:
print(current_app.config['DEBUG'])
print(current_app.config['UPDATE_PERIOD'])
Now, I am running my init.py:
python3 init.py
* Serving Flask app "init" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: on
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 666-659-182
which is okay, how it should be.
Here I expect that app.config['DEBUG'] = True and app.config['UPDATE_PERIOD'] = 100.0
And I am trying to extract this vars in ex.py.
The problem is: when I execute: python3 ex.py I expect this:
True
100.0
but eventually I am getting this:
False
Traceback (most recent call last):
File "ex.py", line 10, in <module>
print(current_app.config['UPDATE_PERIOD'])
KeyError: 'UPDATE_PERIOD'
so I cannot get how app_context() feature is working whereas I think I am doing the same things as written in docs.
There is an option to import in ex.py:
from init import app
but I want to get working instance without complex import since my application is quite big.
Can anyone please help me with this..?
Thank you in advance!

Multiple Flask Application in single uwsgi

I have a flask application with uwsgi configuration. This flask process requests such as addition, subtraction and multiplication. Now in my project structure i have a single app and this app is called in uwsgi config. But now i need to have separate flask application for each operation i.e flask1 for processing addition and flask2 for processing subtraction and so on. I am totally a beginner and have no idea how to achieve this through uwsgi.
I have heard about uwsgi emperor mode but doesn' have idea on it
My app file :
from myapp import app
if __name__ == __main__:
app.run()
wsgi config
module = wsgi:app
You could do this by using Werkzeug's Dispatcher Middleware.
With a sample application like this:
# application.py
from flask import Flask
def create_app_root():
app = Flask(__name__)
#app.route('/')
def index():
return 'I am the root app'
return app
def create_app_1():
app = Flask(__name__)
#app.route('/')
def index():
return 'I am app 1'
return app
def create_app_2():
app = Flask(__name__)
#app.route('/')
def index():
return 'I am app 2'
return app
from werkzeug.middleware.dispatcher import DispatcherMiddleware
dispatcher_app = DispatcherMiddleware(create_app_root(), {
'/1': create_app_1(),
'/2': create_app_2(),
})
You can then run this with gunicorn:
gunicorn --bind 0.0.0.0:5000 application:dispatcher_app
And test with curl:
$ curl -L http://localhost:5000/
I am the root app%
$ curl -L http://localhost:5000/1
I am app 1%
$ curl -L http://localhost:5000/2
I am app 2%
This seems to work by issuing a redirect, which is the reason for the -L flag here.

flask error: from app import views ImportError: cannot import name 'views'

So I am just starting a project in flask and I am using the proper folder structure for the first time and I keep getting this error. I am confused as to why and haven't faced this problem before.
I have tried renaming files and using from . import views but to no avail.
app.py
from flask import Flask
from app import views
app = Flask(__name__)
views.py
from app import app
#app.route('/')
def index():
return "Hello World!"
run.py
from app import app
app.run(debug=True)
Folder structure:
app
static
templates
app.py
run.py
views.py
tmp
Traceback (most recent call last):
File "app.py", line 2, in
from app import views
File "/Users/Josh/PycharmProjects/web1/app/app.py", line 2, in
from app import views
ImportError: cannot import name 'views'
app.py
from flask import Flask
app = Flask(__name__)
import views
views.py
from app import app
#app.route('/')
def hello():
return "Hello World!"
run.py
from app import app
app.run(debug=True)

How to deploy flask backend with waitress server to the internet?

I programmed a flask backend, and made it work on my local network (wifi, ethernet etc). However I can't manage to expand it so external searches reach it. The code for the backend looks like this:
import os
from flask import Flask, flash, request, redirect, url_for, send_from_directory
from waitress import serve
other imports...
app = Flask(__name__)
app.secret_key = os.urandom(24)
.....
if __name__ == '__main__':
serve(app,host='0.0.0.0',port=5000)
How should I give the server an external IP?
If I can make a suggestion, did you try using gevent? It provides a WSGI standalone server for you to replace the built-in option shipped with Flask.
It is very straightforward to use it:
pip install gevent
And you can plug into your app like this:
import os
from gevent.pywsgi import WSGIServer # Imports the WSGIServer
from gevent import monkey; monkey.patch_all()
from flask import Flask, flash, request, redirect, url_for, send_from_directory
app = Flask(__name__)
app.secret_key = os.urandom(24)
if __name__ == '__main__':
LISTEN = ('0.0.0.0',5000)
http_server = WSGIServer( LISTEN, app )
http_server.serve_forever()
Gevent also provides support for SSL
You can use it on its own or along with gunicorn or circusd
I hope it helps you!

Flask uWSGI application structure and python3 imports

I have a basic flask-restful application with a structure that looks like this as recommended on the flask website.
/application
/application
/config.py
/__init__.py
/wsgi.ini
Slightly irrelevant, but config.py is generated by our CD server.
wsgi.ini looks likes this
[uwsgi]
module = application:app
master = true
processes =5
socket = /tmp/application.sock
chmod-socket = 660
vacuum = true
die-on-term = true
and __init__.py looks something like this
import config
from flask import Flask, request, g
from flask_restful import Resource, Api, abort
app = Flask(__name__)
api = Api(app)
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True)
Now when I try to startup the application using uwsgi --ini wsgi.ini I get this error:
File "./application/__init__.py", line 2, in <module>
import config
Originally __init__.py was called main.py and I executed that to debug, which is why the import is now wrong. I'm guess I will need to change the import to be from .config import *
My question is two fold:
Could I have avoided the import problem completely. ie is there a way in python3 to import sibling modules that will work for both approaches
is my wsgi.ini in the correct place, or should it be in the inner application directory?
Python 3.x dropped support for infra-package relative imports. You need to use an absolute import:
from application import config
or the new spelling of relative imports:
from . import config
If you need to also support legacy versions of Python you can enable this behavior with:
from __future__ import absolute_import

Resources