首页 > 解决方案 > 未找到注册网址

问题描述

我们已经使用 Flask 实现了二合一后端。对于网站本身(我们称之为tekid),我们没有遇到任何问题。但是对于管理门户(我们称之为tekid-admin),即使使用相同的视图注册表,WSGI 服务器(开发和生产)对所有请求都返回404 NOT FOUND

相关代码

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/我们在网站上尝试runtekid):

$ 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>

环境

标签: flask

解决方案


因此,基本上从 Flask 和/或 Werkzeug 文档(我不记得原始来源)来看,Flask 只能从不超过2 个(?)层递归识别导入的应用程序实例。

也就是说,应用程序无法识别哪个是要使用的实际实例,而是创建了一个没有任何注册 URL 的空实例。

解决方案是简单地重构代码并在每个文件中导入应用程序实例,并执行与 tekid/urls/www.py 和 tekid/urls/adm.py 相同的操作来导入 CLI 文件中的 URL 注册表。


推荐阅读