Package: ringding
ringding - Simple framework to create awesome WebSocket APIsWhat is ringding?Ringding is a framework to communicate between a Python server and JavaScript client(s) based on WebSocket.
Compared to Web API frameworks like Flask or FastAPI, the ringding API is specified in a more "Python-API-style" way using classes rather than using decorators and "magic strings".
The call of API functions on the JavaScript side also looks more like function calls.When do I want to use ringding?When you want to call function on your server and don't want to provide a full-fledged REST-API.When you want to minimize the overhead from HTTP-headers (especially in Single-Page-Applications / SPAs).When you want to publish a Python-API to a JavaScript client.When the server should notify the clients about events.What technology does ringding use?Ringding is transmitting the data using WebSockets.How do I use ringding?Ringding provides a JavaScript-client and a Python server.
The JavaScript client ringdingjs is hosted by the server on the endpoint/client.js.
But you can also extractringdingjs.jsfrom source and put it somewhere in your
project. It is located inclients/js/ringdingjs.js. You will want to use the
corresponding package.json for Node since Node not support WebSockets by default.
If you want to use ringdingjs in browser apps, you don't need any dependencies.An example Python backend:importringdingclassMyApi:defget_name(self):return'Alfred'defsum(self,a,b):returna+bif__name__=='__main__':ringding.RdServer(port=8001).serve(MyApi)In NodeJS, you can use ringding like this:const{RD,CallApi}=require('ringdingjs')asyncfunctioncommunicate(){awaitRD.connect('ws://localhost:8001')constname=awaitCallApi().MyApi.get_name()console.log('The name is',name)// You can provide keyword arguments to a function call.letsum=awaitCallApi().MyApi.sum({a:5,b:2})// You can also use the more flexible direct call:letanother_sum=awaitRD.call("MyApi.sum(*)",{a:4,b:2})console.log('The sum is: ',sum)RD.disconnect()}communicate()Alternatively in a browser, you can connect and call the sum-function like this:<head><metacharset="UTF-8"><title>Hello ringding</title></head><body><div>Calling "API.sum()" with arguments {a: 5, b: 2}"</div><div>Response:<spanid="response"></span></div></body><scriptdata-main="scripts/app"src="http://localhost:8001/client.js"></script><script>asyncfunctionrun_example(){// Connect to serverawaitRD.connect('ws://localhost:8001')// Send a messageconstresponse=awaitCallApi().MyApi.sum({a:5,b:2})// Read the responseconsole.log('Response:',response)document.getElementById('response').innerText=String(response)}run_example()</script></html>Other featuresChained callsWith chained calls you can call multiple parameterized functions on a server:RD.call('Api.create_user(*user_data).get_hash(hash_type), {user_data: {name: 'Fido', age: 42}, hash_type: 'md5'}Advanced return typesYou can return every JSON-supported datatype (including lists and dicts with simple datatypes) or dataclasses.importringdingimportdataclasses@dataclasses.dataclassclassAdvancedReturnType:name:strage:intclassApi:defget_user(self):returnAdvancedReturnType('Fido',42)if__name__=='__main__':ringding.RdServer(port=8001).serve(Api)The corresponding JavaScript call is thisconstresponse=awaitCallApi().Api.get_user()console.log(response.name)// "Fido"console.log(response.age)// 42Nested APIsI would recommend to use properties for nested Sub-API's on python sideimportringdingclassNested:defdo_something(self):return'I did something'classApi:@propertydefNestedApi(self):returnNested()if__name__=='__main__':ringding.RdServer(port=8001).serve(Api)And the JavaScript-call would beCallApi().Api.NestedApi.do_something()A word on TypescriptYou might want to create an own object of CallApi() and cast you API specification to that object.
That way you could get an API with autocompletion powered by Typescript.RoadmapAn interface to browse API's and their documentation