1
1
from __future__ import print_function
2
2
3
- import itertools
4
3
import os
5
- import random
6
4
import sys
7
5
import collections
8
6
import importlib
14
12
import mimetypes
15
13
16
14
from functools import wraps
15
+ from future .moves .urllib .parse import urlparse
17
16
18
17
import flask
19
18
from flask_compress import Compress
25
24
from .fingerprint import build_fingerprint , check_fingerprint
26
25
from .resources import Scripts , Css
27
26
from .development .base_component import ComponentRegistry
28
- from .exceptions import PreventUpdate , InvalidResourceError
27
+ from .exceptions import PreventUpdate , InvalidResourceError , ProxyError
29
28
from .version import __version__
30
29
from ._configs import get_combined_config , pathname_configs
31
30
from ._utils import (
@@ -1332,7 +1331,8 @@ def enable_dev_tools(
1332
1331
1333
1332
if dev_tools .silence_routes_logging :
1334
1333
logging .getLogger ("werkzeug" ).setLevel (logging .ERROR )
1335
- self .logger .setLevel (logging .INFO )
1334
+
1335
+ self .logger .setLevel (logging .INFO )
1336
1336
1337
1337
if dev_tools .hot_reload :
1338
1338
_reload = self ._hot_reload
@@ -1444,6 +1444,7 @@ def run_server(
1444
1444
self ,
1445
1445
host = os .getenv ("HOST" , "127.0.0.1" ),
1446
1446
port = os .getenv ("PORT" , "8050" ),
1447
+ proxy = os .getenv ("DASH_PROXY" , None ),
1447
1448
debug = False ,
1448
1449
dev_tools_ui = None ,
1449
1450
dev_tools_props_check = None ,
@@ -1470,6 +1471,14 @@ def run_server(
1470
1471
env: ``PORT``
1471
1472
:type port: int
1472
1473
1474
+ :param proxy: If this application will be served to a different URL
1475
+ via a proxy configured outside of Python, you can list it here
1476
+ as a string of the form ``"{input}::{output}"``, for example:
1477
+ ``"http://0.0.0.0:8050::https://my.domain.com"``
1478
+ so that the startup message will display an accurate URL.
1479
+ env: ``DASH_PROXY``
1480
+ :type proxy: string
1481
+
1473
1482
:param debug: Set Flask debug mode and enable dev tools.
1474
1483
env: ``DASH_DEBUG``
1475
1484
:type debug: bool
@@ -1550,25 +1559,49 @@ def run_server(
1550
1559
]
1551
1560
raise
1552
1561
1553
- if self ._dev_tools .silence_routes_logging :
1554
- # Since it's silenced, the address doesn't show anymore.
1562
+ # so we only see the "Running on" message once with hot reloading
1563
+ # https://stackoverflow.com/a/57231282/9188800
1564
+ if os .getenv ("WERKZEUG_RUN_MAIN" ) != "true" :
1555
1565
ssl_context = flask_run_options .get ("ssl_context" )
1556
- self .logger .info (
1557
- "Running on %s://%s:%s%s" ,
1558
- "https" if ssl_context else "http" ,
1559
- host ,
1560
- port ,
1561
- self .config .requests_pathname_prefix ,
1562
- )
1566
+ protocol = "https" if ssl_context else "http"
1567
+ path = self .config .requests_pathname_prefix
1568
+
1569
+ if proxy :
1570
+ served_url , proxied_url = map (urlparse , proxy .split ("::" ))
1571
+
1572
+ def verify_url_part (served_part , url_part , part_name ):
1573
+ if served_part != url_part :
1574
+ raise ProxyError (
1575
+ """
1576
+ {0}: {1} is incompatible with the proxy:
1577
+ {3}
1578
+ To see your app at {4},
1579
+ you must use {0}: {2}
1580
+ """ .format (
1581
+ part_name ,
1582
+ url_part ,
1583
+ served_part ,
1584
+ proxy ,
1585
+ proxied_url .geturl (),
1586
+ )
1587
+ )
1588
+
1589
+ verify_url_part (served_url .scheme , protocol , "protocol" )
1590
+ verify_url_part (served_url .hostname , host , "host" )
1591
+ verify_url_part (served_url .port , port , "port" )
1563
1592
1564
- # Generate a debugger pin and log it to the screen.
1565
- debugger_pin = os . environ [ "WERKZEUG_DEBUG_PIN" ] = "-" . join (
1566
- itertools . chain (
1567
- "" . join ([ str ( random . randint ( 0 , 9 )) for _ in range ( 3 )])
1568
- for _ in range ( 3 )
1593
+ display_url = (
1594
+ proxied_url . scheme ,
1595
+ proxied_url . hostname ,
1596
+ ( ":{}" . format ( proxied_url . port ) if proxied_url . port else "" ),
1597
+ path ,
1569
1598
)
1570
- )
1599
+ else :
1600
+ display_url = (protocol , host , ":{}" .format (port ), path )
1601
+
1602
+ self .logger .info ("Running on {}://{}{}{}" .format (* display_url ))
1571
1603
1572
- self .logger .info ("Debugger PIN: %s" , debugger_pin )
1604
+ if not os .environ .get ("FLASK_ENV" ):
1605
+ os .environ ["FLASK_ENV" ] = "development"
1573
1606
1574
1607
self .server .run (host = host , port = port , debug = debug , ** flask_run_options )
0 commit comments