在之前代的demo中看到app.run()
,然后启动一个应用程序,通过localhost:5000
就能访问我们的视图函数。我们每次更改代码就需要手动重启,还有就是外网不能访问,或者同局域网其他机器不能访问,这些原因都藏在app.run()
方法参数中。
app.run源码
def run(self, host=None, port=None, debug=None, load_dotenv=True, **options):
"""Runs the application on a local development server.
Do not use ``run()`` in a production setting. It is not intended to
meet security and performance requirements for a production server.
Instead, see :ref:`deployment` for WSGI server recommendations.
If the :attr:`debug` flag is set the server will automatically reload
for code changes and show a debugger in case an exception happened.
If you want to run the application in debug mode, but disable the
code execution on the interactive debugger, you can pass
``use_evalex=False`` as parameter. This will keep the debugger's
traceback screen active, but disable code execution.
It is not recommended to use this function for development with
automatic reloading as this is badly supported. Instead you should
be using the :command:`flask` command line script's ``run`` support.
.. admonition:: Keep in Mind
Flask will suppress any server error with a generic error page
unless it is in debug mode. As such to enable just the
interactive debugger without the code reloading, you have to
invoke :meth:`run` with ``debug=True`` and ``use_reloader=False``.
Setting ``use_debugger`` to ``True`` without being in debug mode
won't catch any exceptions because there won't be any to
catch.
:param host: the hostname to listen on. Set this to ``'0.0.0.0'`` to
have the server available externally as well. Defaults to
``'127.0.0.1'`` or the host in the ``SERVER_NAME`` config variable
if present.
:param port: the port of the webserver. Defaults to ``5000`` or the
port defined in the ``SERVER_NAME`` config variable if present.
:param debug: if given, enable or disable debug mode. See
:attr:`debug`.
:param load_dotenv: Load the nearest :file:`.env` and :file:`.flaskenv`
files to set environment variables. Will also change the working
directory to the directory containing the first file found.
:param options: the options to be forwarded to the underlying Werkzeug
server. See :func:`werkzeug.serving.run_simple` for more
information.
.. versionchanged:: 1.0
If installed, python-dotenv will be used to load environment
variables from :file:`.env` and :file:`.flaskenv` files.
If set, the :envvar:`FLASK_ENV` and :envvar:`FLASK_DEBUG`
environment variables will override :attr:`env` and
:attr:`debug`.
Threaded mode is enabled by default.
.. versionchanged:: 0.10
The default port is now picked from the ``SERVER_NAME``
variable.
"""
# Change this into a no-op if the server is invoked from the
# command line. Have a look at cli.py for more information.
if os.environ.get("FLASK_RUN_FROM_CLI") == "true":
from .debughelpers import explain_ignored_app_run
explain_ignored_app_run()
return
if get_load_dotenv(load_dotenv):
cli.load_dotenv()
# if set, let env vars override previous values
if "FLASK_ENV" in os.environ:
self.env = get_env()
self.debug = get_debug_flag()
elif "FLASK_DEBUG" in os.environ:
self.debug = get_debug_flag()
# debug passed to method overrides all other sources
if debug is not None:
self.debug = bool(debug)
_host = "127.0.0.1"
_port = 5000
server_name = self.config.get("SERVER_NAME")
sn_host, sn_port = None, None
if server_name:
sn_host, _, sn_port = server_name.partition(":")
host = host or sn_host or _host
# pick the first value that's not None (0 is allowed)
port = int(next((p for p in (port, sn_port) if p is not None), _port))
options.setdefault("use_reloader", self.debug)
options.setdefault("use_debugger", self.debug)
options.setdefault("threaded", True)
cli.show_server_banner(self.env, self.debug, self.name, False)
from werkzeug.serving import run_simple
try:
run_simple(host, port, self, **options)
finally:
# reset the first request information if the development server
# reset normally. This makes it possible to restart the server
# without reloader and that stuff from an interactive shell.
self._got_first_request = False
在app.run方法中传递这么几个参数:host=None, port=None, debug=None, load_dotenv=True
1.run参数
host参数
host参数:要监听的主机名。
if __name__ == '__main__':
app.run(host='192.168.0.9')
上面示例代码将host设置192.168.0.9
,所以启动服务后就只能通过192.168.0.9:500
来访问视图视图函数。一般host设置0.0.0.0
,设置成’0.0.0.0’如果在本机启动服务,通过局域网访问本机ip + port就可以访问视图函数,如果部署到服务器上,任何机器都可以通过服务器域名 + port来访问视图函数。建议设置0.0.0.0
port端口号
port:要监听主机的端口号,默认是5000
,
注意
:设置一般端口号时不要一些常用服务的端口号一样。如网页的端口号是8080
,mysql的端口号是3036
,pgsql的端口5432
。
if __name == '__main__':
app.run(host='0.0.0.0', port='5000')
debug参数
debug: 如果是True开启调试模式,如果Flase关闭调试模式。一般在本地开发时,需要打开调试模式。
打开调试模式的好处就是:
- 在更改代码后,不需要重新启动服务器
- 如果代码运行出错,在网页上会具体抛出代码错误的原因,方便代码快速地位
load_dotenv参数
load_dotenv: 加载最近的.env
和.flaskenv
文件来设置环境变量,一般不需要设置。
2.配置文件
开发项目中,都会创建一个配置文件,配置文件有什么好处?需要小伙伴们自行百度下。
文件结构
fisher
|-config.py
|-fisher.py
config.py
Flask读取配置
#要注意这里config文件路径,是相对入口文件的位置路径
app.config.from_object('config')
print(app.config['DEBUG'])
fisher.py
from flask import Flask
app = Flask(__name__)
#读取config中配置
app.config.from_object('config')
@app.route('/')
def index():
return 'index'
#设置debug配置
app.run(host='0.0.0.0', port='5000', debug= app.config['DEBUG'])
3.from_boject
使用app.config.from_object来装置配置,配置文件中的配置必须是大写
,否则会被忽略
config.py
DEBUG = True
+ Host = '127.0.0.1'
fisher.py
from flask import Flask
app = Flask(__name__)
#读取config中配置
app.config.from_object('config')
+ print(app.config['Host'])
@app.route('/')
def index():
return 'index'
#设置debug配置
app.run(host='0.0.0.0', port='5000', debug= app.config['DEBUG'])
运行fisher.py
文件,发现会抛出一个错误,KeyError: 'Host'
意思是app.config['Host']
没有Host变量,可是我们明明在config.py中定义Host=127.0.0.1
变量,原因就是使用app.config.from_object来加载配置时,配置文件变量必须是大写
。
将config.py中的Host
修改为大写HOST
,然后修改fisher.py
中
print(app.config['HOST'])
然后重启fisher.py
文件,发现在控制台输出:
127.0.0.1
4.app中config默认参数
我们使用app.config来加载配置文件,那么app.config默认参数是什么,下面是源码
#: Default configuration parameters.
default_config = ImmutableDict(
{
"ENV": None,
"DEBUG": None,
"TESTING": False,
"PROPAGATE_EXCEPTIONS": None,
"PRESERVE_CONTEXT_ON_EXCEPTION": None,
"SECRET_KEY": None,
"PERMANENT_SESSION_LIFETIME": timedelta(days=31),
"USE_X_SENDFILE": False,
"SERVER_NAME": None,
"APPLICATION_ROOT": "/",
"SESSION_COOKIE_NAME": "session",
"SESSION_COOKIE_DOMAIN": None,
"SESSION_COOKIE_PATH": None,
"SESSION_COOKIE_HTTPONLY": True,
"SESSION_COOKIE_SECURE": False,
"SESSION_COOKIE_SAMESITE": None,
"SESSION_REFRESH_EACH_REQUEST": True,
"MAX_CONTENT_LENGTH": None,
"SEND_FILE_MAX_AGE_DEFAULT": timedelta(hours=12),
"TRAP_BAD_REQUEST_ERRORS": None,
"TRAP_HTTP_EXCEPTIONS": False,
"EXPLAIN_TEMPLATE_LOADING": False,
"PREFERRED_URL_SCHEME": "http",
"JSON_AS_ASCII": True,
"JSON_SORT_KEYS": True,
"JSONIFY_PRETTYPRINT_REGULAR": False,
"JSONIFY_MIMETYPE": "application/json",
"TEMPLATES_AUTO_RELOAD": None,
"MAX_COOKIE_SIZE": 4093,
}
)
在源码中我们可以找到config[‘DEBUG’]默认参数None
5.入口文件if__name__作用
大家看到过别人python代码中,入口文件代码经常会有下面一段代码
if __name__ == '__main__':
app.run(host='0.0.0.0', port='5000', debug=app.config['DEBUG'])
我们来讨论下为什么添加这么一段代码,在python中如果别人导入你这个模块,如果不加判断,那么也会执行这段代码,这是我们不希望的。还有一个原因,在生产环境下,我们部署代码到服务器上,通常是使用nginx + uwsgi
方式,uwsgi会加载入口文件
来启动一个服务,而不在使用flask自带的app.run启动服务。如果没有这个判断,那么在服务器上就会启动两个服务,这个是不允许的。