flask - 未找到注册网址
问题描述
我们已经使用 Flask 实现了二合一后端。对于网站本身(我们称之为tekid
),我们没有遇到任何问题。但是对于管理门户(我们称之为tekid-admin
),即使使用相同的视图注册表,WSGI 服务器(开发和生产)对所有请求都返回404 NOT FOUND。
相关代码
CLI 条目注册为
tekid
->tekid.cli.www:cli
tekid-admin
->tekid.cli.adm:cli
以下是我们用来保存 Flask 应用程序对象的代码:
# -*- coding: utf-8 -*-
"""Module entrypoint of TekID website."""
# in `tekid/app/www.py` for `tekid`
from tekid.urls.www import app
# in `tekid/app/adm.py` for `tekid-admin`
from tekid.urls.adm import app
以下是我们用于 CLI 输入的代码:
# -*- coding: utf-8 -*-
"""CLI for TekID website."""
import click
import flask
import tekid.core.typing as typing
# in `tekid/cli/www.py` for `tekid`
from tekid.app.www import app
# in `tekid/cli/adm.py` for `tekid-admin`
from tekid.app.adm import app
__all__ = ['cli']
@click.group(cls=flask.cli.FlaskGroup, create_app=lambda: app)
def cli() -> typing.NoneType:
"""Management script for the TekID website."""
以下是我们用于路由注册的代码(我们使用的是 Flask 本身提出的集中注册机制):
# tekid/urls/www.py & tekid/urls/adm.py (same when testing)
# -*- coding: utf-8 -*-
"""URL routing for TekID website."""
# pylint: disable=wrong-import-position
from tekid.core.macro import FLASK as app
__all__ = ['app']
###############################################################################
# load HTML pages
from tekid.urls.pages import * # pylint: disable=unused-wildcard-import
# index.html
app.add_url_rule('/', view_func=load_index)
... # same routing registry codes
预期行为
注意:tekid
并且tekid-admin
应该给出相同的输出
该routes
命令将如下所示:
$ tekid routes
# or
$ tekid-admin routes
Endpoint Methods Rule
-------------- ----------------- -----------------------------------
load_contact GET, POST /contact/
load_expertise GET /expertise/
load_index GET /
load_news GET, POST /news/
...
static GET /static/<path:filename>
curl http://127.0.0.1:5000/
我们在网站上尝试run
(tekid
):
$ tekid run
* Environment: development
* Debug mode: on
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 332-955-135
/fakepath/.venv/lib/python3.7/site-packages/flask/sessions.py:220: UserWarning: The session cookie domain is an IP address. This may not work as intended in some browsers. Add an entry to your hosts file, for example "localhost.localdomain", and use that instead.
"The session cookie domain is an IP address. This may not work"
127.0.0.1 - - [07/Nov/2019 17:20:03] "GET / HTTP/1.1" 200 -
$ curl http://127.0.0.1:5000
<!--
_______ _ _____ _____ _ _ _
|__ __| | | |_ _| __ \ | | | | | |
| | ___| | __ | | | | | | | | | |_ __| |
| |/ _ \ |/ / | | | | | | | | | __/ _` |
| | __/ < _| |_| |__| | | |___| || (_| |_
|_|\___|_|\_\_____|_____/ |______\__\__,_(_)
-->
... (the actual HTML page)
实际行为
使用与上述相同的配置,我们curl http://127.0.0.1:5000/
在run
管理门户 ( tekid-admin
) 上尝试:
$ tekid-admin run
* Environment: development
* Debug mode: on
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: ***-***-***
/fakepath/.venv/lib/python3.7/site-packages/flask/sessions.py:220: UserWarning: The session cookie domain is an IP address. This may not work as intended in some browsers. Add an entry to your hosts file, for example "localhost.localdomain", and use that instead.
"The session cookie domain is an IP address. This may not work"
127.0.0.1 - - [07/Nov/2019 17:06:25] "GET / HTTP/1.1" 404 -
$ curl http://127.0.0.1:5000
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>404 Not Found</title>
<h1>Not Found</h1>
<p>The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.</p>
环境
- Python版本:3.7.4
- 烧瓶版本:1.1.1
- Werkzeug 版本:0.16.0
解决方案
因此,基本上从 Flask 和/或 Werkzeug 文档(我不记得原始来源)来看,Flask 只能从不超过2 个(?)层递归识别导入的应用程序实例。
也就是说,应用程序无法识别哪个是要使用的实际实例,而是创建了一个没有任何注册 URL 的空实例。
解决方案是简单地重构代码并在每个文件中导入应用程序实例,并执行与 tekid/urls/www.py 和 tekid/urls/adm.py 相同的操作来导入 CLI 文件中的 URL 注册表。
推荐阅读
- php - 遇到格式不正确的数值“php 7.1”
- java - 如何截取验证码并将其放入 JFrame
- python - 如何使连接 4 件到底部?
- javascript - 如何根据 JavaScript 对象有条件地输出数据?
- spring - 从不同浏览器同时登录的用户...如何强制注销第一个用户
- django - 为什么 Django-CMS 不直接链接到我的 Cloudfront CDN 并为 CKEditors 静态文件获取 404?
- c++ - Raspberry Pi 3 上的 QML 性能
- amazon-redshift - Redshift:查询计划中的嵌套循环联接
- node.js - 为什么这行得通?Spotify API 调用 node.js
- powershell - 使用 powershell 编辑电子邮件并保留 HTML 格式