在Cherrypy中运行多个类

9 投票
2 回答
6926 浏览
提问于 2025-04-17 14:31

我正在尝试搭建一个小网站,里面有一个索引页面,还有一个我想放在 /api 下的接口。

比如说:

class Site(object):
    @cherrypy.expose
    def index(self):
        return "Hello, World!"
    @cherrypy.expose
    def contact(self):
        return "Email us at..."
    @cherrypy.expose
    def about(self):
        return "We are..."

class Api(object):
    @cherrypy.expose
    def getSomething(self, something):
        db.get(something)
    @cherrypy.expose
    def putSomething(self, something)

所以,我希望能够访问 mysite.com/contact 和 mysite.com/Api/putSomething。

如果我使用 cherrypy.quickstart(Site()),我只能看到 Site 下面的页面。

我觉得有办法把 Api 类映射到 /Api 下,但我找不到这个方法。

2 个回答

8

正如fumanchu提到的,你可以通过多次调用cherrypy.tree.mount来为你的网站创建不同的子部分。下面是我正在开发的一个网站的简化版本,这个网站包含了前端网页应用和一个RESTful API:

import cherrypy
import web

class WebService(object):

    def __init__(self):
        app_config = {
            '/static': {
                # enable serving up static resource files
                'tools.staticdir.root': '/static',
                'tools.staticdir.on': True,
                'tools.staticdir.dir': "static",
            },
        }

        api_config = {
            '/': {
                # the api uses restful method dispatching
                'request.dispatch': cherrypy.dispatch.MethodDispatcher(),

                # all api calls require that the client passes HTTP basic authentication
                'tools.authorize.on': True,
            }
        }

        cherrypy.tree.mount(web.Application(), '/', config=app_config)
        cherrypy.tree.mount(web.API(), '/api', config=api_config)

    # a blocking call that starts the web application listening for requests
    def start(self, port=8080):
        cherrypy.config.update({'server.socket_host': '0.0.0.0', })
        cherrypy.config.update({'server.socket_port': port, })
        cherrypy.engine.start()
        cherrypy.engine.block()

    # stops the web application
    def stop(self):
        cherrypy.engine.stop()

创建一个WebService的实例会初始化两个不同的网页应用。第一个是我的前端应用,它位于web.Application,并且会在/这个地址上提供服务。第二个是我的RESTful API,它位于web.API,并且会在/api这个地址上提供服务。

这两个视图的配置也不同。例如,我指定了API使用方法分发,并且访问它需要通过HTTP基本认证来进行身份验证。

一旦你创建了WebService的实例,你可以根据需要调用启动或停止,它会处理所有的清理工作。

这真是很酷的东西。

8

更新(2017年3月13日):下面的原始回答已经有些过时,但我保留它是为了反映最初提出的问题。

官方文档现在有一个关于如何实现这一点的详细指南。


原始回答:

看看默认的调度器。这是关于调度的完整文档。

引用文档中的内容:

root = HelloWorld()
root.onepage = OnePage()
root.otherpage = OtherPage()

在上面的例子中,网址 http://localhost/onepage 会指向第一个对象,而网址 http://localhost/otherpage 会指向第二个对象。像往常一样,这个搜索是自动进行的。

这个链接提供了更多细节,并且下面有一个完整的示例。

import cherrypy

class Root:
    def index(self):
        return "Hello, world!"
    index.exposed = True

class Admin:
    def user(self, name=""):
        return "You asked for user '%s'" % name
    user.exposed = True

class Search:
    def index(self):
        return search_page()
    index.exposed = True

cherrypy.root = Root()
cherrypy.root.admin = Admin()
cherrypy.root.admin.search = Search()

撰写回答