0

标题是不言自明的,所以我只展示一些我到目前为止尝试过的代码:

来自https://stackoverflow.com/a/713950

import cherrypy
from cherrypy import expose

cherrypy.config.update({'server.socket_port': 80})

class Test:
    @expose
    def test_call(self):
        return "Testing"

cherrypy.quickstart(Test())

此外,从另一个 SO 帖子中,有以下两个变体:

cherrypy.config.update({
    'server.socket_port': 80,
    '/': {
        'request.dispatch': cherrypy.dispatch.MethodDispatcher(),
        'tools.trailing_slash.on': False
    }
})

class Test:
    def test_call(self, *args):
        return json.dumps(args)
    test_call.exposed = True

class API:
    def __init__(self):
        self.Test = Test()

class Root:
    def __init__(self):
        self.API = API()


cherrypy.tree.mount(Root())
cherrypy.quickstart(Root())

此处建议使用变体:CherryPy 中未找到路径

cherrypy.quickstart(cherrypy.Application(Root(), '/', {}))

我运行这些并访问http://mysite.com/test_call,或者在另一种情况下访问 mysite.com/api/test/test_call,除了返回 404 之外,这些似乎都没有做任何事情。想法?

如果它只是让我公开一些函数调用来转储 JSON,我完全愿意尝试不同的框架。我不需要任何花哨或酷炫的东西,只要发挥作用即可。

编辑:显然我的问题是服务器默认期望是本地主机,这基本上让我成为一个白痴。添加cherrypy.server.socket_host = "mydomain.com"修复此问题。

4

2 回答 2

1

标题与示例不匹配,并且表明您可能被 REST 专家误导,在您链接的答案评论中,他们倾向于将所有内容称为“RPC”,这偏离了他们的 CRUD 有限资源视角。JSON RPC 是某种规范,它定义了请求和响应的 JSON 结构。它看起来像这样。

--> {"jsonrpc": "2.0", "method": "subtract", "params": [42, 23], "id": 1}
<-- {"jsonrpc": "2.0", "result": 19, "id": 1}

您的示例与它无关,也与 REST 无关。它们是不了解主题的复制粘贴。让我们稍微整理一下。

  1. CherryPy 有多个调度选项。默认调度程序将请求 URL 段映射到 Python 对象树,就像/API/Testroot.API.Test您的第二个示例中一样。它的常见用途是常规的 GET/POST Web 流。
  2. 如果你想实现一个 RESTful API,这里有专门的手册页:在 CherryPy 中创建 RESTful 应用程序。它简要解释了MethodDispatcher.
  3. 如果实际的 JSON RPC 是您想要的,那么您可以查看python-jsonrpc具有 CherryPy 适配器的包。
  4. 但是,如果您想要实现的只是返回一个带有适当内容类型标头的 JSON 字符串,CherryPy 有一个专门的工具,因此没有必要手动完成。

以下是#4 的示例。

#!/usr/bin/env python
# -*- coding: utf-8 -*-


import cherrypy


config = {
  'global' : {
    'server.socket_host' : '127.0.0.1',
    'server.socket_port' : 8080,
    'server.thread_pool' : 8
  }
}

class Api:

  @cherrypy.expose
  @cherrypy.tools.json_out()
  def oneway(self):
    '''Just open http://127.0.0.1:8080/api/oneway'''
    return {
      'foo' : 'bar',
      'baz' : 'another one'
    }

  @cherrypy.expose
  @cherrypy.tools.json_in()
  @cherrypy.tools.json_out()
  def twoway(self):
    '''You can call it like:
    curl -X POST -H "Content-Type: application/json" \
      -d '{"foo":123,"bar":"baz"}' http://127.0.0.1:8080/api/twoway
    '''

    data = cherrypy.request.json
    return data.items()


if __name__ == '__main__':
  cherrypy.quickstart(Api(), '/api', config)
于 2014-11-29T17:38:27.440 回答
0

我尝试了下面的第一个脚本(有 2 个注释,如果使用端口 80,则使用 root 用户)。通过“http://127.0.0.1 /test_call”访问它。有用。

您应该更具体地提出您的问题(给出您的代码),以便观众知道如何帮助解决它。

#! /usr/bin/python3

import cherrypy
from cherrypy import expose

## NOTE 1 - using 0.0.0.0
cherrypy.config.update({'server.socket_host' : '0.0.0.0', 'server.socket_port': 80})

class Test:
    @expose
    def test_call(self):
        return "Testing"

## NOTE 2 - a work around for python3 and cherrypy v3.x
## work around OSERR issue - OSError: Port 7766 not bound on '10.220.203.233'
## refer to http://stackoverflow.com/questions/767575/crp-hello-world-error
def fake_wait_for_occupied_port(host, port): return
cherrypy.process.servers.wait_for_occupied_port = fake_wait_for_occupied_port

cherrypy.quickstart(Test())
于 2014-03-09T12:38:04.350 回答