【问题标题】:How to launch a Bottle application over a CherryPy standalone web server?如何在 CherryPy 独立 Web 服务器上启动 Bottle 应用程序?
【发布时间】:2015-04-03 04:25:11
【问题描述】:

我有一个使用瓶子框架开发的 python 网络应用程序。我的瓶子应用程序是提供返回 JSon 数据的方法的 Web API,因此不需要静态内容。我正在尝试使用 CherryPy 服务器将其部署到生产环境,该服务器应该对生产应用程序来说是健壮的。

我的 web_api.py 文件(我的瓶子应用程序)看起来像这样:

from bottle import Bottle, request

app = Bottle()

@app.get('/stuff')
def do_stuff():
    '''
    Method that does stuff.
    '''
    stuff = {'data': 'some data'}
    # Return the environment info as Json data
    return stuff

我有一个 server.py 文件,用于在 CherryPy 服务器上启动 Bottle 应用程序,如下所示:

from my_package.web_api import app
from cherrypy.wsgiserver import CherryPyWSGIServer

server = CherryPyWSGIServer(
    ('0.0.0.0', 80),
    app,
    server_name='My_App',
    numthreads=30)

server.start()

所以当我使用这个命令运行我的服务器时:

python server.py

我的服务器已成功启动并按预期开始监听端口 80。但是,一旦我启动我的网络服务器,我就无法再停止它了。我试过 Ctrl + C 可以与开发服务器一起使用,但在这里没有效果。我是否以正确的方式启动服务器?运行后如何停止?这是通过 CherryPy 启动 Bottle 应用的正确方法吗?

顺便说一句,我在 Windows 8 中运行 python 2.7。

【问题讨论】:

  • 现在(2017 年)查看此问题的任何人都应该被告知,这在最新版本的 CherryPy 中不起作用。 Since version 9.0.0(2017 年 1 月),cherrypy.wsgiserver 移至 Cheroot

标签: python cherrypy bottle


【解决方案1】:

你的代码是正确的,你只需要添加一个try/catch语句:

from my_package.web_api import app
from cherrypy.wsgiserver import CherryPyWSGIServer

server = CherryPyWSGIServer(
    ('0.0.0.0', 80),
    app,
    server_name='My_App',
    numthreads=30)

try:
    server.start()
except KeyboardInterrupt:
    server.stop()

您可能还想考虑使用wsgi-request-logger 或类似的东西进行一些日志记录。

这是在 cherrypy 中托管 WSGI 应用程序的三种替代方法:

import cherrypy as cp
from cherrypy.wsgiserver import CherryPyWSGIServer
from cherrypy.process.servers import ServerAdapter


from bottle import Bottle

app = Bottle()

@app.get('/stuff')
def do_stuff():
    '''
    Method that does stuff.
    '''
    stuff = {'data': 'some dataX'}
    return stuff

def run_decoupled(app, host='0.0.0.0', port=8080, **config):
    server = CherryPyWSGIServer((host, port), app, **config)
    try:
        server.start()
    except KeyboardInterrupt:
        server.stop()

def run_in_cp_tree(app, host='0.0.0.0', port=8080, **config):
    cp.tree.graft(app, '/')
    cp.config.update(config)
    cp.config.update({
        'server.socket_port': port,
        'server.socket_host': host
    })
    cp.engine.signals.subscribe() # optional
    cp.engine.start()
    cp.engine.block()

def run_with_adapter(app, host='0.0.0.0', port=8080, config=None, **kwargs):
    cp.server.unsubscribe()
    bind_addr = (host, port)
    cp.server = ServerAdapter(cp.engine,
                              CherryPyWSGIServer(bind_addr, app, **kwargs),
                              bind_addr).subscribe()
    if config:
        cp.config.update(config)
    cp.engine.signals.subscribe() # optional
    cp.engine.start()
    cp.engine.block()

run_in_cp_treerun_with_adapter 函数使用的是cherrypy 引擎,这使得plugins 的使用能够拥有现成的自动重载、pidfile、守护进程、信号管理和一些其他好东西,以及创造自己的可能性。

请注意,您还可以使用 WSGIPathInfoDispatcher 在 CherryPyWSGIServer 上附加多个 wsgi 应用程序。

【讨论】:

  • 哇!很好的答案@cyraxjoe,非常感谢!我整天都在寻找这个信息,但没有运气。谢谢:)
  • 顺便问一下@cyraxjoe,你有没有一个例子来说明如何在像我这样的设置中使用wsgi-request-logger?在 CherryPy 上使用瓶子?我遵循了他们的文档,但我得到的是空日志。
  • @Cas 我刚刚写了一个blog post,其中包含访问/错误日志用例的更长解释。希望对您有所帮助。
  • 太棒了,你是最棒的!
【解决方案2】:

在 2019 年尝试将任何 WSGI 服务器连接到我的 BottlePy 应用程序被证明是相当棘手的(对于像我这样的菜鸟)。 我尝试连接几个,大部分时间都花在 CherryPy 上,这改变了他的语法。

对我来说最简单的竟然是女服务员https://waitress.readthedocs.io/en/latest/usage.html 在我弄清楚如何在女服务员身上使用它之后,我也在cherrypy中得到了它。所以:

CherryPy http://docs.cherrypy.org/en/latest/advanced.html?highlight=WSGi#host-a-foreign-wsgi-application-in-cherrypy

1)在导入后添加

import cherrypy as cp

app  = bottle.Bottle()

2) 将“@bottle”路由更改为“@app”

3)将此添加为主函数

 cp.tree.graft(app, '/')
 cp.server.start()

女服务员

1)在导入后添加

import waitress 

app  = bottle.Bottle()

2)将此添加为主函数

 waitress.serve(app, listen='*:44100')

3) 将“@bottle”路由更改为“@app”

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-26
    • 2020-10-01
    • 1970-01-01
    • 2015-01-29
    • 2023-04-02
    • 1970-01-01
    相关资源
    最近更新 更多