سؤال

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