Multiple flask applications served by a single gunicon server - python

I have a service, which contains 2 Flask-applications - let's name them app and monitoring_app running on different ports. monitoring_app is an utility service which provides metrics collected with prometheus_client. I have faced up with an issue trying run them under the Gunicorn server properly.
I have read through the similar topic:
Multiple Flask Application in single uwsgi
but it seems my problem can't be solved with Dispatcher Middleware.
I can start these applications without Gunicorn like this:
from threading import Thread
import os
from my_project import create_app, create_monitoring_app
def start_app(my_app):
my_app.run(host="localhost",
debug=True,
port=int(os.environ.get("API_PORT", "5000")),
threaded=True,
use_reloader=False)
if __name__ == "__main__":
app = create_app()
app_thread = Thread(target=start_app, daemon=True, args=(app,))
app_thread.start()
monitoring_app = create_monitoring_app()
monitoring_app.run(host="localhost",
port=int(os.environ.get("OPS_PORT", "5001")),
threaded=True,
use_reloader=False,
debug=True)
It works ok for development, but it runs under Flask development server which is not ok for production environment. With Gunicorn I can start them separately:
gunicorn "my_project:create_monitoring_app()" -b "[::]:$OPS_PORT" &
gunicorn "my_project:create_app()" -b "[::]:$API_PORT"
but then they will be in different interpreters and I can't use prometheus_client of app in monitoring_app what is critical for me
What can I do to achieve same behavior as if I run these applications from my development environment? Or may be I am doing something wrong and I should do it in another way?

Related

Flask App - Local Development Environment - changes not reflecting

I have a Flask App that I am running locally and testing. Every time, I make a change in the Application code, the changes would reflect on the dev environment http://127.0.0.1:8000/ with a simple browser refresh.
Now, I have to terminate the Flask App Ctrl X + Ctrl C and then reboot / relaunch the App. I am using gunicorn to launch the Flask App.
Not sure what changed, but how do I configure the App such that the changes take effect on refresh?
I have the following line of code in init.py:
if __name__ == '__main__':
run_simple('0.0.0.0', 80, app, use_reloader=True, use_debugger=True)
Gunicorn has its own system to reload the worker process when the application code changes. You can use the --reload CLI flag to activate the auto-reloading dev mode.
gunicorn --reload app:app
You can add additional files to the watcher via the --reload-extra-file FILES arg.
Try
if __name__ == '__main__':
app.run(debug=True)
Also using Gunicorn
web: gunicorn wsgi:app

Python Flask - how to run a web-visible server from a docker container (on a mac)?

I downloaded a pre-built docker container, it has a web server running on Python's Flask. The web service is visible on localhost, but I want to access the web service from the web.
I see a lot of similar questions, and all of them have some arcane answers. Some recommend using nginx or gunicorn as a web server. I don't know enough to route this pre-built container to some other container or network interface. Additionally, it appears that Mac has a smaller set of network operators than other OS.
Does the code below properly expose a web service to the web on Mac?
Is it my router using some sort of sandboxed network rules to avoid devices on the network seeing each other?
I see a recommendation to add CMD ["python3", "-m", "flask", "run", "--host=0.0.0.0"] , but I don't know where
import os
import sys
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from com.my.server import app
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080, debug=False)
# I tried to find my local ip:
# app.run(host='192.168.0.2', port=8080, debug=False) # does not work
In the console:
* Serving Flask app "com.my.server" (lazy loading)
* Environment: production
Debug mode: off
* Running on http://0.0.0.0:8080/ (actually 127.0.0.1:8080)

Serving Flask app with waitress on windows

I am able to run a webserver using the following code
from flask import Flask
from waitress import serve
app = Flask(__name__, static_url_path='/static')
...
serve(app, port=8080)
The problem is that I can access it only from the machine where it is running, if I try to access it using the ipv4 ip, it doesn't work. Am I missing a step?
Simple example,try it!
I hope it will help you.
app1.py
from flask import Flask
app = Flask(__name__)
# app.run(host='0.0.0.0', port=8080,debug=True)
waitress_server.py
from waitress import serve
import app1
serve(app1.app, host='0.0.0.0', port=8080)
Then run below command
python waitress_server.py
Waitress now provides a simple command line Utility called waitress-serve for running the Flask Application. Please note that this answer is valid for Waitress 1.30. The command line arguments could change in future.
If your Flask application is called myapplication and the method which instantiates your application is called create_app, then you can run the command below. This will launch the server listening on port 8080 by default.
waitress-serve --call "myapplication:create_app"
If you wish to launch it on port 80 (http), then all you need to do is:
waitress-serve --port=80 --call "myapplication:create_app"
D:\flaskapps>waitress-serve --port 80 --call "dlrlsummarizer:create_app"
Serving on http://ADITHYA-PC:80
Waitress serve command line arguments.
Flask 1.0 production deployment tutorial.
Try using
serve(app, host='0.0.0.0', port=8080)
I ran into this question and looking something similar.
After looking at the documentation and combined with your original request, I tested
serve(app, port=8080, host="x.x.x.x")
Where x.x.x.x is my host ip address.
It works fine on my end.
Complete code
from flask import Flask
from waitress import serve
app = Flask(__name__)
...
serve(app, port=8080, host="x.x.x.x")
I realize this question was probably based in a miss-diagnosed firewall or NAT issue, but in case people come here actually wanting to serve a Flask app with waitress on windows properly (as a service), I want to point to my answer here, so that it can be of use and receive some feedback.
from flask import Flask
from waitress import serve
app = Flask(__name__)
#app.route("/")
def hello_world():
return "<p>Hello stay healthy.</p>"
if __name__ == "__main__":
serve(app, host="127.0.0.1", port=8080)
Problem may persist in host. You can use host="127.0.0.1" in your program.
Save your program in app.py file.
Run your program.
The server will be accessible at http://localhost:8080
I just realized that can be reached by computers in the same network, but not from computers outside of the network
You need to forward the port in your router and use your public IP address.
To be able to use your internal PC (behind the router) you need to forward in the router the externl port 8080 to internal port 8080 and IP address of your server.
In this conditions you can access your server from outside your network using your external IP. That is OK if you have a static IP address allocated by your provider. If not than you can use a free DNS provider (I use DnsExit) which will provide you with a name for your external IP address. This way you can access your server with a name even if the IP address from your service provider changes from time to time.

Flask at first run: Do not use the development server in a production environment

I installed the Flask plugin in PyCharm Community Edition and I just have this simple code in my flask app:
from flask import Flask
app = Flask(__name__)
#app.route('/')
def index():
return '<h1>Hello!</h1>'
if __name__ == "__main__":
app.run(debug=True)
And I get this message:
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead
* Restarting with stat
* Debugger is active!
* Debugger PIN: 123-456-789
* Running on http://127.0.0.1:5000/
Why am I getting this error when I run Flask?
A previous version of the message read "Do not use the development server in a production environment."
For deploying an application to production, one option is to use Waitress, a production WSGI server.
Here is an example of using waitress in the code.
from flask import Flask
app = Flask(__name__)
#app.route("/")
def index():
return "<h1>Hello!</h1>"
if __name__ == "__main__":
from waitress import serve
serve(app, host="0.0.0.0", port=8080)
Running the application:
$ python hello.py
Waitress also provides a command line utility waitress-serve. To use that, you can modify the code to the following:
from flask import Flask
app = Flask(__name__)
#app.route("/")
def index():
return "<h1>Hello!</h1>"
def create_app():
return app
Then we can use waitress-serve as the following:
waitress-serve --port=8080 --call hello:create_app
And BTW, 8080 is the default port.
To validate the deployment, open a separate window:
% curl localhost:8080
<h1>Hello!</h1>%
Or directly in your browser http://localhost:8080/.
Other alternatives to deploy your app include Gunicorn and uWSGI. For more details, please refer to the flask deploy doc.
As of Flask 2.2, the development server always shows this warning, it is not possible to disable it. The development server is not intended for use in production. It is not designed to be particularly efficient, stable, or secure. Use a production WSGI server instead. See the deployment docs from Flask for more information.
That warning is just a warning though, it's not an error preventing your app from running. If your app isn't working, there's something else wrong with your code.
That warning applies to the development server, not Flask itself. The Flask framework is appropriate for any type of application and deployment.
To avoid these messsages, inside the CLI (Command Line Interface), run these commands.
export FLASK_APP=app.py
export FLASK_ENV=development
export FLASK_DEBUG=0
flask run
If for some people (like me earlier) the above answers don't work, I think the following answer would work (for Mac users I think)
Enter the following commands to do flask run
$ export FLASK_APP=hello.py
$ export FLASK_ENV=development
$ flask run
Alternatively you can do the following (I haven't tried this but one resource online talks about it)
$ export FLASK_APP=hello.py
$ python -m flask run
source: For more
Try gevent:
from flask import Flask
from gevent.pywsgi import WSGIServer
app = Flask(__name__)
#app.route('/api', methods=['GET'])
def index():
return "Hello, World!"
if __name__ == '__main__':
# Debug/Development
# app.run(debug=True, host="0.0.0.0", port="5000")
# Production
http_server = WSGIServer(('', 5000), app)
http_server.serve_forever()
Note: Install gevent using pip install gevent
This worked for me on windows:
$env:FLASK_APP="flask_project.py"
$env:FLASK_ENV="development"
flask run
flask_project.py is on the same path as my virtual environment.

unable to deploy the python pyramid web apps to heroku

This is the Error logs I find in the heroku when deploying the python pyramid application. I have followed the each and every steps the python pyramid documentation has. Where have I exactly missed not able to figure out.
I doubt if my way of creating run file is incorrect. I have created a run.py
file and added the following code into it.
#!/bin/bash
set -e
python setup.py develop
python runapp.py
You cannot host a web app like that. You need a proper server, for example gunicorn - see the Pyramid docs on how to run with gunicorn, that is what needs to go in your Procfile. You don't need a run.py.
Try this:
Profile
web: ./run
run
#!/bin/bash
set -e
python setup.py develop
python runapp.py
runapp.py
#Heroku Startup
import os
from paste.deploy import loadapp
from waitress import serve
if __name__ == "__main__":
port = int(os.environ.get("PORT", 5000))
app = loadapp('config:production.ini', relative_to='.')
serve(app, host='0.0.0.0', port=port)
requirements.txt
pyramid
pyramid_chameleon
pyramid_debugtoolbar
waitress
<add other dependencies here>
runtime.txt
python-3.3.0 #or whatever version you are running. Take this out

Categories

Resources