How to deploy flask backend with waitress server to the internet? - python-3.x

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!

Related

error when putting the views in a separate views.py file in flask application

I am building a flask application and the main file of this application is named app.py
which is like this:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from config import Development
from flask_migrate import Migrate
app = Flask(__name__)
app.config.from_object(Development)
db = SQLAlchemy(app)
migrate = Migrate(app, db)
##app.route('/')
#def index():
# return "Blog Home"
from mod_admin import admin
from mod_users import users
app.register_blueprint(admin)
app.register_blueprint(users)
but i am trying to put all views in a file which is named views.py and looks like this:
from app import app
#app.route('/')
def index():
return "Blog Home"
both app.py and views.py are in the same directory. when I run :
flask run
I will get the url and when I put it in the browser (tried a couple of them including firefox and Chrom), I will get 404 error. however if I remove views.py and uncomment the view in the app.py it works perfectly and I can see the message on the browser.
do you know what could be the issue when I put the view in views.py and remove that from app.py?
Remove the app import from views and you need to use a view blueprint instead.
Views.py should look something like this:
bp = Blueprint('views', __name__, url_prefix='/', template_folder='./templates')
#bp.route('/')
def homepage():
return "blog home"
and app.py should have the lines:
from views import bp
app.register_blueprint(bp)

Python Flask app is not running on heroku servers

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')

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!

Can't run python app on digitalocean after adiing swagger

I have added flask_swagger_ui in my app. In Pycharm everything works good.
After uploading this code on digitalocean i have problem. I've also installed flask-swagger-ui on server and in uwsgi log have this:
File "/var/www/html/control/app.py", line 9
<<<<<<< HEAD
^
SyntaxError: invalid syntax
unable to load app 0 (mountpoint='') (callable not found or import error)
in app.py:
import os
from flask import Flask
from flask_restful import Api
from flask_jwt import JWT
from security import authenticate, identity
from resources.user import UserRegister
from flask_swagger_ui import get_swaggerui_blueprint #this is line 9

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