关于python:在CherryPy中创建基本的JSONRPC API-获取404

Creating a basic JSONRPC API in CherryPy - Getting 404s

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

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

1
2
3
4
5
6
7
8
9
10
11
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帖子中,以下内容有两个变体:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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

中找不到路径

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

我运行这些文件并访问http://mysite.com/test_call,或者访问mysite.com/api/test/test_call,这些文件似乎都没有做任何事情,只是返回了404。有想法吗?

如果让我公开一些转储JSON的函数调用,我完全可以尝试使用其他框架。我不需要任何花哨或炫酷的功能,只需运行即可。

编辑:显然我的问题是服务器在默认情况下期望是localhost,这基本上使我成为白痴。添加cherrypy.server.socket_host ="mydomain.com"可以解决此问题。


标题与示例不符,表明您可能被REST专家误导了,在您链接的答案注释中,他们往往将所有内容都称为" RPC",这与CRUD限制的资源angular背道而驰。 JSON RPC是特定的规范,它定义了用于请求和响应的JSON结构。看起来像这样。

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

您的示例与REST无关。它们是复制粘贴,没有理解该主题。让我们整理一下。

  • CherryPy具有服务器调度选项。默认调度程序将请求URL段映射到Python对象树,例如第二个示例中的/API/Testroot.API.Test。它的常规用法是常规的GET / POST Web流。
  • 如果要实现RESTful API,请在这里为其专用的手册页:在CherryPy中创建RESTful应用程序。它简要说明了MethodDispatcher的样式和用法。
  • 如果您想要的是实际的JSON RPC,则可以查看具有CherryPy适配器的python-jsonrpc软件包。
  • 但是,如果您要实现的只是返回带有适当的content-type标头的JSON字符串,CherryPy拥有专用的工具,因此没有必要手动进行操作。
  • 这里是#4的示例。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    #!/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)

    我尝试了以下第一个脚本(带有2个注释,如果使用端口80,则使用root用户)。通过" http:// 127.0.0.1 / test_call"进行访问。有效。

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    #! /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())