使用 CherryPy/Cherryd 启动多个 Flask 实例

发布于 2024-11-07 08:49:27 字数 1211 浏览 5 评论 0原文

根据 SO/SF 和其他网站上的建议,我使用 CherryPy 作为 WSGI 服务器来启动我用 Flask 构建的 Python Web 服务器的多个实例。每个实例都在自己的端口上运行并位于 Nginx 后面。我应该指出,下面的内容确实对我有用,但我很困扰,因为我以错误的方式处理事情,而且它“偶然”起作用。

这是我当前的cherrypy.conf 文件:

[global]
server.socket_host = '0.0.0.0'
server.socket_port = 8891
request.dispatch: cherrypy.dispatch.MethodDispatcher()
tree.mount = {'/':my_flask_server.app}

无需深入了解我的 Flask 服务器,以下是它的启动方式:

import flask
app = flask.Flask(__name__)

@app.route('/')
def hello_world():
    return "hello"

这是我在命令行上发出的使用 Cherryd 启动的命令:

cherryd -c cherrypy.conf -i my_flask_server

问题是:

  1. < p>将 Flask 包装在 CherryPy 中仍然是在生产中使用 Flask 的首选方法吗? https://stackoverflow.com/questions/4884541/cherrypy-vs-flask-werkzeug< /p>
  2. < p>这是使用 .conf 文件启动 CherryPy 并导入 Flask 应用程序的正确方法吗?我已经搜索了 CherryPy 文档,但找不到任何与我在此处具体尝试执行的操作相匹配的用例。

  3. 在单台计算机上启动多个 CherryPy/Flask 实例以执行多个cherryd 命令(使用 -d 等进行守护进程)以及每个要使用的端口(8891、8892 等)的唯一 .conf 文件的正确方法是吗?或者是否有更好的“CherryPy”方法来实现此目的?

感谢您的任何帮助和见解。

Per suggestions on SO/SF and other sites, I am using CherryPy as the WSGI server to launch multiple instances of a Python web server I built with Flask. Each instance runs on its own port and sits behind Nginx. I should note that the below does work for me, but I'm troubled that I have gone about things the wrong way and it works "by accident".

Here is my current cherrypy.conf file:

[global]
server.socket_host = '0.0.0.0'
server.socket_port = 8891
request.dispatch: cherrypy.dispatch.MethodDispatcher()
tree.mount = {'/':my_flask_server.app}

Without diving too far into my Flask server, here's how it starts:

import flask
app = flask.Flask(__name__)

@app.route('/')
def hello_world():
    return "hello"

And here is the command I issue on the command line to launch with Cherryd:

cherryd -c cherrypy.conf -i my_flask_server

Questions are:

  1. Is wrapping Flask inside CherryPy still the preferred method of using Flask in production? https://stackoverflow.com/questions/4884541/cherrypy-vs-flask-werkzeug

  2. Is this the proper way to use a .conf file to launch CherryPy and import the Flask app? I have scoured the CherryPy documentation, but I cannot find any use cases that match what I am trying to do here specifically.

  3. Is the proper way to launch multiple CherryPy/Flask instances on a single machine to execute multiple cherryd commands (daemonizing with -d, etc) with unique .conf files for each port to be used (8891, 8892, etc)? Or is there a better "CherryPy" way to accomplish this?

Thanks for any help and insight.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

心凉 2024-11-14 08:49:27

我不能代表 Flask,但我可以代表 CherryPy。这看起来像是“正确的方式”......大多数情况下。关于 MethodDispatcher 的那一行是无操作的,因为它只影响 CherryPy 应用程序,并且您似乎没有安装任何应用程序(只是一个 Flask 应用程序)。

关于第3点,你说得对。 CherryPy 允许您在同一进程中运行多个 Server 对象,以便侦听多个端口(或协议),但它没有任何用于启动多个进程的糖。正如您所说,具有不同配置文件的多个cherryd命令是如何做到这一点的(除非您想使用更集成的集群/配置管理工具,例如 蛋怪)。

I can't speak for Flask, but I can for CherryPy. That looks like the "proper way"...mostly. That line about a MethodDispatcher is a no-op since it only affects CherryPy Applications, and you don't appear to have mounted any (just a single Flask app instead).

Regarding point 3, you have it right. CherryPy allows you to run multiple Server objects in the same process in order to listen on multiple ports (or protocols), but it doesn't have any sugar for starting up multiple processes. As you say, multiple cherryd commands with varying config files is how to do it (unless you want to use a more integrated cluster/config management tool like eggmonster).

岁月静好 2024-11-14 08:49:27

术语:安装与嫁接

原则上,这是通过cherrypy提供烧瓶应用程序的正确方法,只是对您的命名进行快速说明:

这里值得注意的是,tree.mount不是配置键本身 - tree 将导致使用参数 'mount', {'/': my_flask_server.app 调用 cherrypy._cpconfig._tree_config_handler(k, v) }

_tree_config_handler 根本不使用 key 参数,因此在您的配置中,“mount”只是路径映射的特定字典的任意标签。它也不会“挂载”应用程序(毕竟它不是 CherryPy 应用程序)。我的意思是,它不是 cherrypy.tree.mount(…) ,而是 cherrypy.tree.graft 是一个任意 WSGI 处理程序到您的“脚本名称”上(路径,但使用 CherryPy 术语)名称空间。

Cherrypy 的日志消息有点误导性地说“Mountedon /”]

这是一个很重要的一点,因为与 mount 不同,使用移植时,您无法指定更多选项,例如应用程序的静态文件服务或该路径上的流响应。

因此,我建议将 tree.mount 配置键更改为描述性的内容,这样就不会导致阅读太多有关 CherryPy 中发生的情况的语义(因为 cherrypy 中存在 .tree.mount 方法)由于该配置。例如,如果您只是在该字典中映射一个应用程序,则为tree.flask_app_name(可以有许多tree指令,所有这些指令都被合并到路径命名空间中)或 tree.wsgi_delegates 如果您在该字典中映射了许多应用程序。

使用 CherryPy 提供附加内容而不制作应用程序

另外,如果您希望cherrypy 为您的应用程序提供静态文件服务,则无需创建样板cherrypy 应用程序来保存该配置。您只需使用适当的附加配置安装 None 即可。如果将以下文件放入启动cherryd以提供静态内容的目录中,则足以让CherryPy从子目录“static”提供静态内容(将cherryd调用为cherryd -ccherrypy.conf -i my_flask_server -我静态:

static.py

import cherrypy
# next line could also have config as an inline dict, but
# file config is often easier to handle
cherrypy.tree.mount(None, '/static-path', 'static.conf')

static.conf

# static.conf
[/]
tools.staticdir.on = True
tools.staticdir.root = os.getcwd()
tools.staticdir.dir = 'static'
tools.staticdir.index = 'index.html'

Terminology: Mounting vs Grafting

In principle this is a proper way to serve a flask app through cherrypy, just a quick note on your naming:

It is worth noting here that tree.mount is not a configuration key by itself - tree will lead to cherrypy._cpconfig._tree_config_handler(k, v) being called with the arguments 'mount', {'/': my_flask_server.app}.

The key parameter is not used at all by the _tree_config_handler so in your config "mount" is just an arbitrary label for that specific dict of path mappings. It also does not "mount" the application (it's not a CherryPy app after all). By that I mean, it does not cherrypy.tree.mount(…) it but rather cherrypy.tree.grafts an arbitrary WSGI handler onto your "script-name" (paths, but in CherryPy terminology) namespace.

Cherrypy's log message somewhat misleadingly says "Mounted <app as string> on /"]

This is a somewhat important point since with graft, unlike mount, you cannot specify further options such as static file service for your app or streaming responses on that path.

So I would recommend changing the tree.mount config key to something descriptive that does not invite reading too much semantics about what happens within CherryPy (since there is the cherrypy.tree.mount method) due to that config. E.g., tree.flask_app_name if you're just mapping that one app in that dict (there can be many tree directives, all of them just getting merged into the paths namespace) or tree.wsgi_delegates if you map many apps in that dict.

Using CherryPy to serve additional content without making an app of it

Another side note, if you want cherrypy to e.g. provide static file service for your app, you don't have to create a boilerplate cherrypy app to hold that configuration. You just have to mount None with the appropriate additional config. The following files would suffice to have CherryPy to serve static content from the subdirectory 'static' if they are put into the directory where you launch cherryd to serve static content (invoke cherryd as cherryd -c cherrypy.conf -i my_flask_server -i static:

static.py

import cherrypy
# next line could also have config as an inline dict, but
# file config is often easier to handle
cherrypy.tree.mount(None, '/static-path', 'static.conf')

static.conf

# static.conf
[/]
tools.staticdir.on = True
tools.staticdir.root = os.getcwd()
tools.staticdir.dir = 'static'
tools.staticdir.index = 'index.html'
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文