Server information in a Flask app - python

Intend
I want to be able to tell which server is running my Flask app.(Either Werkzeug or Gunicorn) And additionally if it is being proxied by NGINX or Apache.
Problem
I think I can get the response with JavaScript and get the server header, but In the case of it being proxy by NGINX or Apache, I won't be able to tell whatever is gunicorn or werkzeug that I is running under hood.
Is there a way to tell the server within the flask app?

Some servers will add SERVER_SOFTWARE into the os environment. Gunicorn will do this.
#app.route('/server')
def server():
return os.environ.get('SERVER_SOFTWARE')
Result:

Related

GUNICORN FastAPI Deployment with Proxy

I am currently setting up a FastAPI application to run on an AWS RockyLinux 8 instance with a gunicorn deployment. Most of the documentation that I have read recommends NGINX as a proxy server.
I currently have an Apache sever running on this instance and would rather not install another HTTP daemon if I can help it.
My question is: Why is a proxy HTTP server needed at all? gunicorn seems to run just fine without a proxy HTTP server simply by specifying a port other than 80. Is this a security recommendation or am I missing something?

Serve Flask Server Over HTTPS

I'm learning AWS and I'm currently trying to deploy a Flask API over HTTPS. I set up an EC2 instance running Apache. I've already set up SSL on the site using ELB, and I tried to deploy flask over HTTPS with the following:
if __name__ == '__main__':
context = ("server.crt", "server.key")
app.run(host="0.0.0.0",port=5000,debug=True,ssl_context=context)
However, I don't think the site is even starting the Flask server properply, as even though everything loads and I receive a message that Flask is running on https://0.0.0.0:5000/, sending a simple GET request over the browser doesn't work as the request just never loads and it eventually times out. It's almost behaving as if there is no server running on port 5000.
On the other hand, when I ran this program over http instead of https, it worked perfectly fine. Can anyone help me out in terms of what I should do? Thank you.
Based on the comments.
The solution to the issue was termination HTTPS connections on the ELB. This way, the communication between ELB and EC2 instance can be conducted using HTTP which is simple and easier to manage on the instances.

Flask app on plesk/apache server - how to change port?

I'm new to setting up a server for python apps, slowly getting my head round all the tools and config options.
I'd like to configure a testing instance on an existing server that has plesk and apache installed. I managed to set up the python environment, virtualenv, the flask app inclusive database and run it successfully on http://domain.test:5000 however I'd need to remove the port number from the domain.
Gunicorn seems to be the tool for that, however I'm not sure how to go about it as plesk is apparently installed on port 80 - so is there any way to get this configured on that server with some port hiding/masking/redirect or do I need to move to a standalone server?
Additionally I'd like to add a ssl certificate to that domain but one step at the time...
The method run on a Flask application takes a keyword argument port:
from flask import Flask
app = Flask(__name__)
app.run(port=80)
Of course you'll need root privileges to run on port 80

Flask app run with Gunicorn async workers appears less efficient than dev server

I've got a web app developed in Flask. The setup is simple. The app is running on Gunicorn. All requests are proxied through the nginx. The Flask app itself makes HTTP requests to external API. The HTTP requests from the flask app to the external API are initiated by AJAX calls from the javascript code in the frontend. The external API returns data in JSON format to the Flask app and the back to the frontend.
The problem is that when I run this app in development mode with the option multithreaded = True I can see that the JSON data get returned asynchronously to the server and I can see the result on the frontend page very quickly.
However, when I try to run the app in production mode with nginx and gunicorn I see that the JSON data get returned sequentially - quit slowly, one by one. It seems that due to some reason the HTTP requests to the external API get blocked.
I use supervisor on linux Ubuntu Server 16.04. This is how I start gunicorn through supervisor:
command = /path/to/project/env/bin/gunicorn -k gevent --worker-connections 1000 wsgi:app -b localhost:8500
It seems that gunicorn does not handle the requests asynchronously, although it should.
As experiment I ran the Flask app using it's built in wsgi server (NOT gunicorn) in development mode, with debug=True and multithreaded=True. All requests were still proxied through the nginx. The JSON data returned much quicker, i.e. asynchronously (seems the calls did not block).
I read gunicorn's documentation. It says if I need to make calls to external API, then I should use async workers. I use them but it doesn't work.
All the caching stuff was taken into account. I may assume that I don't use any cache. I cleared it all when I checked the server setups.
What am I missing? How can I make gunicorn run as expected?
Thanks.
I actually solved this problem quite quickly and forgot to post the answer right away. The reason why the gunicorn server did not process the requests acynchronously as I would expect was very simple and stupid. Since I was managing gunicorn through the supervisor after I had changed the config to:
command = /path/to/project/env/bin/gunicorn -k gevent --worker-connections 1000 wsgi:app -b localhost:8500
I forgot to run:
sudo supervisorctl reread
sudo supervisorctl update
It's simple but not obvious though. My mistake was that I expected the config to update automatically after I restart my app on gunicorn using this command:
sudo supervisorctl restart my_app
Yes it restart the app, but not the config of gunicorn.

Running a flask server

So, probably a dumb question, but I am beginning to learn all this so your feedback will be valuable for me.
The question is: In flask documentation it says start the flask server by entering the command 'python hello.py' and I do it successfully to see the output on localhost:5000. Now, I have a shared hosting plan and if I upload this file over there will i need to initiate the server over there as well like this? If so, when I close the terminal over there, will the flask server shut down (because when I close the terminal on my computer it shuts down the flask server and the results are no more available on localhost:5000)?.. It basically suggests me that I have to keep running the terminal all the time..please tell me what is the basic idea here? Thanks.
What you're asking is how you deploy your app. There are many options, that will depend on your needs, your hosting service, etc.
You should check the flask docs for the options. http://flask.pocoo.org/docs/deploying/
In essence, you'll have your flask app running as a local service on the server, so it's not shut down when you close the terminal, and an HTTP server that somehow proxies requests to that service. I guess the most popular is uWSGI with nginx.
When you upload your code to a remote host, you will need to provide a way to start the server and get things running. How this works is host- and software-dependent. As an example, here is some documentation for how you would fire Flask up on Heroku.

Categories