質問

The title is fairly self-explanatory, so I'll just show some code I've tried so far:

From 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())

Also, from another SO post, two variants on the following:

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())

with a variation suggested here: Path Not Found in CherryPy

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

I run these and access http://mysite.com/test_call or, in the other case, mysite.com/api/test/test_call, and neither of these seem to be doing much of anything except returning a 404. Ideas?

I am completely open to trying a different framework if it'll just let me expose a few function calls to dump JSON. I don't need anything fancy or cool, just functioning.

EDIT: Apparently my problem was that the server was by default expecting to be localhost, which basically makes me an idiot. Adding cherrypy.server.socket_host = "mydomain.com" fixes this.

役に立ちましたか?

解決 2

I tried the first script as below (with 2 notes, using root user if using port 80). Access it by "http:// 127.0.0.1 /test_call". It works.

You should be more specific to raise your question (giving your codes), so the audience knows how to help solve it.

#! /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())

他のヒント

The title doesn't match with examples and is telling that you were likely misguided by REST adepts, in the answer's comments you linked, who tend call everything a "RPC", which deviates from their CRUD-limited resource perspective. JSON RPC is the certain specification, which defines JSON structures for request and response. It looks like this.

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

Your examples have nothing to do with it, as well as with REST. They are a copy-paste without understanding the subject. Let's sort out a little.

  1. CherryPy has serveral dispatching options. Default dispatcher maps request URL segments to Python object tree, like /API/Test to root.API.Test in your second example. Its common use is regular GET/POST web flow.
  2. If you want to implement a RESTful API, here's dedicated manual page for it: Creating RESTful applications in CherryPy. It briefly explains the style and usage of MethodDispatcher.
  3. If actual JSON RPC is what you want, then you can look at python-jsonrpc package, which has CherryPy adapter.
  4. Though, if all you want to achieve is to return a JSON string with appropriate content-type header, CherryPy has a specific tool for it, so there's no point to do it manually.

Here follows example for #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)
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top