This example show how to make JSON-RPC call to Python.
The sample use the same example as before ‘add’ and will return 5.
UPDATE: Some examples that return different types.
use framework "Foundation"
use scripting additions
set theBody to "{
\"jsonrpc\": \"2.0\",
\"method\": \"dict\",
\"params\": [],
\"id\": 1
}"
(*
set theBody to "{
\"jsonrpc\": \"2.0\",
\"method\": \"array\",
\"params\": [],
\"id\": 1
}"
*)
(*
set theBody to "{
\"jsonrpc\": \"2.0\",
\"method\": \"string\",
\"params\": [],
\"id\": 1
}"
*)
(*
set theBody to "{
\"jsonrpc\": \"2.0\",
\"method\": \"integer\",
\"params\": [],
\"id\": 1
}"
*)
(*
set theBody to "{
\"jsonrpc\": \"2.0\",
\"method\": \"float\",
\"params\": [],
\"id\": 1
}"
*)
(*
set theBody to "{
\"jsonrpc\": \"2.0\",
\"method\": \"add\",
\"params\": [2,3],
\"id\": 1
}"
*)
set stringBody to current application's NSString's stringWithString:theBody
set postData to stringBody's dataUsingEncoding:(current application's NSUTF8StringEncoding)
its performJSONRPCRequestWithResponse("http://localhost:9070", postData)
on performJSONRPCRequestWithResponse(URLString, postData)
set theRequest to its createRequestWithJSON(URLString, postData)
set theData to its createResponseFromRequest(theRequest)
set {theResult, theError} to current application's NSJSONSerialization's JSONObjectWithData:theData options:0 |error|:(reference)
if theResult is missing value then error (theError's localizedDescription() as string)
set returnObject to (theResult's valueForKey:"result") as anything
if returnObject is missing value then
return (theResult's valueForKey:"error") as anything
else
return returnObject
end if
end performJSONRPCRequestWithResponse
on createRequestWithJSON(URLString, postData)
set URLString to current application's |NSURL|'s URLWithString:URLString
set theRequest to current application's NSMutableURLRequest's alloc()'s initWithURL:URLString
theRequest's setHTTPMethod:"POST"
theRequest's setHTTPBody:postData
return theRequest
end createRequestWithJSON
on createResponseFromRequest(theRequest)
set theResponse to current application's NSHTTPURLResponse's alloc()'s init()
set {JSONData, theError} to current application's NSURLConnection's sendSynchronousRequest:theRequest ¬
returningResponse:theResponse |error|:(reference)
if JSONData is missing value then error (theError's localizedDescription() as string)
-- debug the JSONData response
log (current application's NSString's alloc()'s initWithData:JSONData ¬
encoding:(current application's NSUTF8StringEncoding)) as string
return JSONData
end createResponseFromRequest
Here is the server in Python, make sure you have the right module installed.
ex. jsonrpcserver The server use port 9070. Have been tested on Python 3.9
There is 2 method you could test ‘ping’ and ‘add’
Ps. I’m still investigate why I couldn’t get it to work in Twisted.
from http.server import BaseHTTPRequestHandler, HTTPServer
from jsonrpcserver import method, Result, Success, dispatch
import math
import datetime
@method
def dict() -> Result:
object = {
"name": "Johnny",
"lastname": "Appleseed",
"phone": "123.456.789",
"math pi": math.pi,
"date stamp": str(datetime.datetime.now()),
"id": 12345678
}
return Success(object)
@method
def array() -> Result:
return Success([math.pi,"some string",[42,"other string"]])
@method
def string() -> Result:
return Success("Some string")
@method
def integer() -> Result:
return Success(42)
@method
def float() -> Result:
return Success(math.pi)
@method
def ping() -> Result:
return Success("pong")
@method
def add(x, y) -> Result:
return Success(x + y)
class TestHttpServer(BaseHTTPRequestHandler):
def do_POST(self):
# Process request
request = self.rfile.read(int(self.headers["Content-Length"])).decode()
response = dispatch(request)
# Return response
self.send_response(200)
self.send_header("Content-type", "application/json")
self.end_headers()
self.wfile.write(response.encode())
if __name__ == "__main__":
HTTPServer(("localhost", 9070), TestHttpServer).serve_forever()