The following is pre-writing for a new Chapter in Leo's documentation.

All comments, suggestions, additions, and corrections are welcome.

-----

leoserver.py is a stand-alone web server that provides access to all of 
Leo's capabilities using Leo's bridge.  leoserver.py is not part of Leo's 
core.

leoclient.py is an example client, written in python. Clients may be 
written in any language. Clients send text requests to the server, in JSON 
format, and receive JSON responses from the server.

This chapter describes how to start the server and the communication 
protocol, that is, the format of the JSON requests and responses.

*Starting the server*

To start the server, execute `python leoserver.py <args>` in a separate 
process, that is, outside of Leo itself. `leoserver -h` prints 
"leoserver.py -a <address> -p <port>"

 By default, the server listens on "localhost" and port 32125. You can 
change these defaults with the --address and --port command-line arguments.

*Communication protocol: requests*
 
The *_do_message* method expects that incoming requests are JSON objects 
that can be converted to a python dict, with the following three keys:

"id": A positive integer.

"action": A string, which is either:
  - The name of public method of this class, prefixed with a '!'.
  - The name of a leo command, without prefix, to be run by _do_leo_command.

"param": A dict to be passed to the called "action" method.

*Communication protocol: requests* 

The *_make_response* and *_make_minimal_response* methods return python 
dicts that are then converted do JSON. All responses contain an 'id' key 
that matches the corresponding requests.

*Archived positions*

Leo's Position objects can not be converted directly to JSON. Instead, 
requests and response contain *archived positions*, that are strings 
representing positions. The server's *_ap_to_p* and *_p_to_ap* methods 
convert between real Leo Positions and archived positions.

*Technical details*

The *ws_handler *function contains the main server loop. It calls Python's 
asyncio.get_event_loop() to start listening on the designated socket and 
port.

ws_handler dispatches incoming requests to the *_do_request* method, which 
then dispatches the requests to the appropriate handler, either in the 
LeoServer class, or (via Leo's bridge) to Leo itself.

 *Exception handling*

Request handlers raise ServerError exceptions for badly formatted user 
requests. The server returns an response describing the error.

The server raises InternalServerError for errors within the server itself. 
The server prints an error message and stops.

Request handlers raise TerminateServer to terminate the server normally.

*Compatibility and future directions*

The present version of leoserver.py exists to support leoInteg: Leo hosted 
on vs code.

In future, features (request handlers) can be added to leoserver.py, but 
features probably will never be removed.

*Acknowledgements*

Félix Malboeuf wrote the original version of leoserver.py including the 
first draft of the all-important The ws_handler function. Edward K. Ream 
helped make the code more pythonic, and provided Leo-specific advice.

Edward

-- 
You received this message because you are subscribed to the Google Groups 
"leo-editor" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/leo-editor/58f65397-b0a5-41b7-a810-b2b185eb06a0n%40googlegroups.com.

Reply via email to