An API is a way to encapsulate all of the publically callable functions for a single application, composition, piece, class, service etc. in one universally accessible place.
Each API object has a name (eg. "server") and a dictionary of functions.
These can then be called:
in SuperCollider code
over OSC (simple call of functions)
via the duplex OSC interface (call and response)
Using a client library like supercollider.js
supercollider.js provides a Node.js based api_server through which you can easily communicate with SuperCollider from javascript either on the server (running under Node) or in a browser (communicating back to Node with websockets).
It uses socket.io which is loads of fun and should prove quite useful for installations and pieces that allow many people to interact using mobile phones over normal webrowsers.
https://github.com/crucialfelix/supercolliderjs
Each Quark can provide a folder called apis/ containing API handler dictionaries.
Post all currently implemented API paths:
You can easily write APIs for your own application just by putting a file containing a dictionary of handlers in:
Your quark is now on the internets.
I know, I hate these.
API 2 always passes in a { arg reply; } callback function while API 1 just used the return value as the result.
API 1 was a bit more confusing to use though for the call and response stuff.
Your old APIs, should you have any, would take just a few minutes to add in the callback, or you can continue to use the old methods:
name |
apiname eg. "server" "synthdef" Convention is lowercase. It must match the case of the apis/{apiname}.api.scd file |
an API
Call API method receiving the results with a callback.
path |
"apiname.method" |
args |
array of arguments |
callback |
Callback that receives the result |
onError |
Optional onError handler. If not supplied than errors will be propagated. |
nothing, the result is returned to the callback
Call API method, waiting the current thread if needed till the result is returned. You should be inside a Routine, { }.defer {}.fork or similiar
path |
"apiname.method" |
args |
array of arguments |
onError |
Optional onError handler. If not supplied than errors will be propagated. |
the result
Call API method, returning the result directly. The handler must not fork or defer. This is vaguely faster and can be used when you know there is no async.
path |
"apiname.method" |
... args |
array of arguments |
return value
All available API paths in the form "apiname.method"
array of strings
an array of the names of all available APIs from all /apis/ folders in all Quarks
array of strings
Array of all loaded APIs as API objects
array of API objects
Load all APIs from apis/ folders in all quarks.
forceReload |
Force reload/reparse |
this
find and load an API from disk. throws an Error if not found or if failed to parse the file.
name |
apiname |
the API
Registers OSC responders. supercollider.js uses this to communicate.
There is an unfinished python implementation in the python folder of this Quark. Any language that can speak OSC and JSON can use these endpoints.
client_id and request_id : are used to identify return messages and are up to the implementation of the api consumer
client_id would usually be a specific web browser, program or other independent entity. supercollider.js uses the socket.io socket id hash
request_id would be a unique id for each request from that client. supercollider.js increments a simple counter: 1,2,3 etc.
fullpath: apiname.methodKey dot separated to make it clear that its not an OSC path
Replies:
result is sent as a JSON string: "{result:result}" so the api consumer needs to have a JSON library available. JSON does not distinguish between Symbol and String so all values are strings. Result may be string, int, float, list, dictionary. Date time not yet implemented. All other objects will be sent as their compile string representation.
Possibly .asJSON could allow objects to support their own JSON representations. Or the constructor arguments / storeArgs could be used to form a JSON response.
addr |
An optional NetAddr (basically an IP address), limiting connections to that specific address. |
recvPort |
Optional port to listen on, otherwise uses the language's default port NetAddr.langPort [57120] |
this
this
add a single handler
selector |
handler name |
func |
handler function |
this
Add a dictionary of handlers to this API.
dict |
The dictionary or dictionary subclass. The example above uses an Event because the notation ( ) is simple to type. |
this
Takes an object and turns it into an API by making each method on the object into a function of the same name.
obj |
the object |
selectors |
methods to turn into handlers |
this
Takes an object and turns it into an API by making each method on the object into a function of the same name.
obj |
the object |
selectors |
selectors to NOT add to the API. |
this
see class method.
selector |
(describe argument here) |
args |
(describe argument here) |
callback |
(describe argument here) |
onError |
(describe argument here) |
(describe returnvalue here)
see class method.
selector |
(describe argument here) |
args |
(describe argument here) |
onError |
(describe argument here) |
(describe returnvalue here)
see class method.
selector |
(describe argument here) |
... args |
(describe argument here) |
(describe returnvalue here)
Register OSC Responders for each method in this API object.
baseCmdName |
The OSC root where the responders are installed: /baseCmdName/method By default /apiname/method |
addr |
Optional limit to a certain NetAddr |
this
(describe method here)
(describe returnvalue here)
List of installed handler names.
array of symbols