How to define the host and port to use in a Flask app?

2

To execute an application in Flask we use the method

app.run()

In this method we can pass configuration parameters, among them:

host, port, debug

By default, the Flask application runs in

host = localhost
port = 5000

So, if we want to change that configuration, we pass it to the run method

app.run(host="10.100.100.10", port=9566)

In the case of wanting to have different configurations for your application (either production, development, testing) you must define a configuration dictionary, something like this:

app.config.update(
    DEBUG=True,
    SECRET_KEY='...'
)

Reading ( link ) I found this attribute:

SERVER_NAME

Quoting the Flask documentation:

  

the name and port number of the server. Required for subdomain support   (e.g .: 'myapp.dev:5000') Note that localhost does not support   subdomains so setting this to "localhost" does not help. Setting a   SERVER_NAME also by default enables URL generation without a request   context but with an application context.

This attribute should change the host and the purto.

Then I defined this:

app.config.update(
    DEBUG=True,
    SERVER_NAME="10.100.100.10:6500"
)

As a result it keeps showing when executing the application

Running in 127.0.0.1:5000

How can I make my application run on another host and port without having to use parameters within the run method?

    
asked by Victor Alvarado 17.03.2018 в 06:02
source

1 answer

1

The SERVER_NAME configuration variable is not to tell Flask to listen to a certain IP and port, but to tell it that is listening to a certain IP and port.

That variable in general is only necessary if the app is listening with a name (or IP) different from the one it offers publicly (because it has, for example, nginx acting as a proxy, or running in a container, or because it is installed on a machine that, through virtual hosting, serves several servers). In that case, flask can not know what its name is: public ports, and instead it needs them to be able to resolve which is the url associated (externally) to a certain route, so that url_for() can work.

As far as I know, the only way to change the IP and port you listen to is to pass it as a parameter to app.run() . Now, instead of passing an IP and ports "prefixed" from the source code, you can perfectly make them read from an external file, or the configuration of the app itself.

For example, the following code takes the configuration value SERVER_NAME and extracts the IP and port from it, to pass them to app.run() :

server_name = app.config['SERVER_NAME']
if server_name and ':' in server_name:
    host, port = server_name.split(":")
    port = int(port)
else:
    port = 5000
    host = "localhost"
app.run(host=host, port=port)

The value of that configuration variable would be fixed elsewhere, for example with the code that you put yourself before. That code would typically not be part of your app, but a configuration file. You could also take it from environment variables, which might be the most appropriate.

Note, however, that since the variable SERVER_NAME is not intended for this purpose, the previous code is not the best way to do it. It is possible that this variable has a value such as: https://mi.servidor.com in which case the trick of splitting by ":" to separate IP and port will not work. It's just an example of how you can use app.config to store information that you can then use within the app. If instead of SERVER_NAME you use your own variable, the better. We could call it for example IP_PUERTO .

Also investigate the flask command, which you can use instead of python to launch the application (in that case the application will not contain a app.run() since it is the flask command that is responsible for invoking it) . To that command you can pass it through the command line the host and port as parameters (and it internally passes them to app.run() when you launch it).

Update

Examining the source code of flask, I see that app.run() actually expects you to pass a host name and if you do not pass it will use 127.0.0.1 , and also expect you to pass a port, but if not raisin takes it from SERVER_NAME (and if it does not find it there, use 5000).

This detail I did not know and it means that in your example, when you put the% "10.100.100.10:6500" in SERVER_NAME , the app should be listening in 127.0.0.1:6500 and not in 127.0.0.1:5000 as you put.

In any case, given that the IP you are putting is a private IP, I do not think you are using SERVER_NAME in the correct way. It should contain the public IP (or better the DNS name) through which you can access your app from the internet.

    
answered by 17.03.2018 / 10:57
source