Как получить текущий номер порта в Flask?

Используя Flask, как я могу получить текущий номер порта, к которому подключена фляжка? Я хочу запустить сервер на случайном порту с помощью порта 0, но мне также нужно знать, в каком порту я нахожусь.

Edit

Думаю, я нашел работу для своей проблемы, хотя это не ответ на вопрос. Я могу выполнить итерацию через порты, начиная с 49152, и попытаться использовать этот порт через app.run(port=PORT). Я могу сделать это в блоке catch try, чтобы, если я получаю ошибку Address already in use, я могу попробовать следующий порт.

Ответы

Ответ 1

Вы не можете легко получить доступ к серверному сокету, используемому Flask, поскольку он скрыт во внутренних стандартах стандартной библиотеки (Flask использует Werkzeug, чей сервер разработки основан на stdlib BaseHTTPServer).

Однако вы можете создать эфемерный порт самостоятельно, а затем закрыть сокет, который его создает, а затем использовать этот порт самостоятельно. Например:

# hello.py
from flask import Flask, request
import socket

app = Flask(__name__)

@app.route('/')
def hello():
    return 'Hello, world! running on %s' % request.host

if __name__ == '__main__':
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.bind(('localhost', 0))
    port = sock.getsockname()[1]
    sock.close()
    app.run(port=port)

предоставит вам номер порта для использования. Пример:

$ python hello.py 
* Running on http://127.0.0.1:34447/

и, просматривая http://localhost:34447/, я вижу

Привет, мир! работает на localhost: 34447

в моем браузере.

Конечно, если что-то другое использует этот порт между закрытием сокета, а затем Flask, открывающим сокет с этим портом, вы получите ошибку "Адрес в использовании", но вы можете использовать эту технику в своем окружающая среда.

Ответ 2

Привязка к порту 0 верна. Это заставит операционную систему выбрать доступный порт между 1024 и 65535 для вас.

Чтобы извлечь выбранный порт после привязки, используйте your_socket.getsockname()[1].

Итак, все, что вам нужно выяснить, - это доступ к гнезду для прослушивания, используемому Flask.

socket.getsockname() docs: http://docs.python.org/library/socket.html#socket.socket.getsockname

Ответ 3

Как указано в @VinaySajip Flask, используйте стандартный серверный сокет, но он никогда не присваивает экземпляр какой-либо переменной, просто создайте его и вызовите serve_forever() в строке.

В любом случае попробуйте извлечь сокет из флеш-приложения, как сказано в @ThiefMaster, мы можем перехватить вызов bind_socket() и прочитать адрес, не заботясь о создании параллельного сокета. Вот мое решение:

from flask import Flask, request
import socketserver

app = Flask("")

original_socket_bind = SocketServer.TCPServer.server_bind
def socket_bind_wrapper(self):
    ret = original_socket_bind(self)
    print("Socket running at {}:{}".format(*self.socket.getsockname()))
    # Recover original implementation
    socketserver.TCPServer.server_bind = original_socket_bind
    return ret

@app.route("/")
def hello():
    return 'Hello, world! running on {}'.format(request.host)

socketserver.TCPServer.server_bind = socket_bind_wrapper   #Hook the wrapper
app.run(port=0, debug=True)

Ответ 4

В большинстве операционных систем в эти дни есть команда под названием netstat, которая даст вам список всех используемых портов, а также какие приложения работают на них, если вы попросите достаточно хорошо.:)

Достаточно легко разобрать с помощью модуля os.popen или subprocess.

Кроме того, вы можете просто отслеживать, какие порты вы используете при запуске каждого сервера...

Кроме того, если вы делаете это изнутри HTTP-запроса, вы можете посмотреть переменную cgi SERVER_PORT из среды wsgi.