-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DASH_PROXY #1289
DASH_PROXY #1289
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,6 @@ | ||
from __future__ import print_function | ||
|
||
import itertools | ||
import os | ||
import random | ||
import sys | ||
import collections | ||
import importlib | ||
|
@@ -14,6 +12,7 @@ | |
import mimetypes | ||
|
||
from functools import wraps | ||
from future.moves.urllib.parse import urlparse | ||
|
||
import flask | ||
from flask_compress import Compress | ||
|
@@ -25,7 +24,7 @@ | |
from .fingerprint import build_fingerprint, check_fingerprint | ||
from .resources import Scripts, Css | ||
from .development.base_component import ComponentRegistry | ||
from .exceptions import PreventUpdate, InvalidResourceError | ||
from .exceptions import PreventUpdate, InvalidResourceError, ProxyError | ||
from .version import __version__ | ||
from ._configs import get_combined_config, pathname_configs | ||
from ._utils import ( | ||
|
@@ -1332,7 +1331,8 @@ def enable_dev_tools( | |
|
||
if dev_tools.silence_routes_logging: | ||
logging.getLogger("werkzeug").setLevel(logging.ERROR) | ||
self.logger.setLevel(logging.INFO) | ||
|
||
self.logger.setLevel(logging.INFO) | ||
|
||
if dev_tools.hot_reload: | ||
_reload = self._hot_reload | ||
|
@@ -1449,6 +1449,7 @@ def run_server( | |
self, | ||
host=os.getenv("HOST", "127.0.0.1"), | ||
port=os.getenv("PORT", "8050"), | ||
proxy=os.getenv("DASH_PROXY", None), | ||
debug=False, | ||
dev_tools_ui=None, | ||
dev_tools_props_check=None, | ||
|
@@ -1475,6 +1476,14 @@ def run_server( | |
env: ``PORT`` | ||
:type port: int | ||
|
||
:param proxy: If this application will be served to a different URL | ||
via a proxy configured outside of Python, you can list it here | ||
as a string of the form ``"{input}::{output}"``, for example: | ||
``"http://0.0.0.0:8050::https://my.domain.com"`` | ||
so that the startup message will display an accurate URL. | ||
env: ``DASH_PROXY`` | ||
:type proxy: string | ||
|
||
:param debug: Set Flask debug mode and enable dev tools. | ||
env: ``DASH_DEBUG`` | ||
:type debug: bool | ||
|
@@ -1555,25 +1564,51 @@ def run_server( | |
] | ||
raise | ||
|
||
if self._dev_tools.silence_routes_logging: | ||
# Since it's silenced, the address doesn't show anymore. | ||
# so we only see the "Running on" message once with hot reloading | ||
# https://stackoverflow.com/a/57231282/9188800 | ||
if os.getenv("WERKZEUG_RUN_MAIN") != "true": | ||
ssl_context = flask_run_options.get("ssl_context") | ||
self.logger.info( | ||
"Running on %s://%s:%s%s", | ||
"https" if ssl_context else "http", | ||
host, | ||
port, | ||
self.config.requests_pathname_prefix, | ||
) | ||
protocol = "https" if ssl_context else "http" | ||
path = self.config.requests_pathname_prefix | ||
|
||
if proxy: | ||
served_url, proxied_url = map(urlparse, proxy.split("::")) | ||
|
||
def verify_url_part(served_part, url_part, part_name): | ||
if served_part != url_part: | ||
raise ProxyError( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are we happy with proxy errors throwing, or would it be better to just show a warning but keep going? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure I understand this: If we throw an error when the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
But I guess that brings up the option to do the reverse of what you're suggesting: ignore I don't think we can do that with the protocol, because if you're using https you also need to provide the cert and key. But I get the impression (@gzork can you confirm this?) that at least in our own use of such proxies, encryption is handled by the proxy itself so There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
That's correct, in our case the encryption is handled by |
||
""" | ||
{0}: {1} is incompatible with the proxy: | ||
{3} | ||
To see your app at {4}, | ||
you must use {0}: {2} | ||
""".format( | ||
part_name, | ||
url_part, | ||
served_part, | ||
proxy, | ||
proxied_url.geturl(), | ||
) | ||
) | ||
|
||
verify_url_part(served_url.scheme, protocol, "protocol") | ||
verify_url_part(served_url.hostname, host, "host") | ||
verify_url_part(served_url.port, port, "port") | ||
|
||
# Generate a debugger pin and log it to the screen. | ||
debugger_pin = os.environ["WERKZEUG_DEBUG_PIN"] = "-".join( | ||
itertools.chain( | ||
"".join([str(random.randint(0, 9)) for _ in range(3)]) | ||
for _ in range(3) | ||
display_url = ( | ||
proxied_url.scheme, | ||
proxied_url.hostname, | ||
(":{}".format(proxied_url.port) if proxied_url.port else ""), | ||
path, | ||
) | ||
) | ||
else: | ||
display_url = (protocol, host, ":{}".format(port), path) | ||
|
||
self.logger.info("Dash is running on %s://%s%s%s\n", *display_url) | ||
self.logger.info(" Warning: This is a development server. Do not use app.run_server") | ||
self.logger.info(" in production, use a production WSGI server like gunicorn instead.\n") | ||
|
||
self.logger.info("Debugger PIN: %s", debugger_pin) | ||
if not os.environ.get("FLASK_ENV"): | ||
os.environ["FLASK_ENV"] = "development" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The complete message you get now (ours plus the built-in Flask message) looks like:
|
||
|
||
self.server.run(host=host, port=port, debug=debug, **flask_run_options) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't do all that much with
self.logger
but what we do we always want the user to see - not just when silencing built-in route logging.