Skip to content
This repository has been archived by the owner on Apr 4, 2024. It is now read-only.

3rd party FAHClient API

Jason Salaz edited this page May 1, 2020 · 4 revisions

Introduction

The v7 Folding@home client supports a new remote interface which allows applications to do the following:

  • Access information about the client.
  • Read and modify the client's configuration.
  • Access information about the work units in the client's queue.
  • Start and stop folding slots.
  • Add, configure or remove folding slots.
  • Access protein models.

The client's GUI, FAHControl, and viewer, FAHViewer, both use this interface so all the functionality they provide and more is accessible.

Historically, third-party software has been written to read the client's log file and reverse-engineer files like queue.dat in order to access client information. These methods were never officially supported and were often broken by changes in the client or core software. The new v7 client will not support these older interfaces. Instead, this new interface will provide a more consistent and officially supported method to access the same information and much more.

Technical Overview

At the lowest level, the client provides a network socket interface which defaults to port 36330. This interface is both usable by a machine and by a human connecting directly with a telnet program.

Client Interface

Socket programming can be challenging so Language specific API layers will be developed to simplify connection to the socket level interface. This will allow programmers to access and control Folding@home clients via a few function calls via a library in their favorite language.

Directly Connecting to the Socket Interface

This socket interface is designed to be usable both by human and machine. A quick way to gain access to this interface is to connect to a locally running client with a telnet program. For example:

telnet localhost 36330
Welcome to the Folding@home Client command server.
>

Typing help at the prompt will give you a list of commands organized into section and information on how to use them.

Depending on the client configuration you may have to use the auth <password> command to get access to other commands. The authorization functionality depends on the configuration options command-allow, command-allow-no-pass, the related deny options and where you connect from.

Attention Telneting is mainly for developers of 3rd party tools. If you use a compatible telnet program and send complete commands from any applications you develop then everything should work fine. The problem is that FAHClient is not compatible with the Windows telnet program (at the moment). The client expects to receive whole commands than a character at a time. If you telnet remotely from a Linux box to your Windows machines it should work fine. You could also try installing a 3rd party telnet program with more options.

Sending Commands

Sending commands to the client is very simple. Commands consist of strings of characters followed by one or more arguments separated by spaces followed by a return character (ASCII #10). Arguments which contain spaces may be escaped with single or double quotes.

For example, to access the value of the pause-on-battery configuration option you would send this command:

option pause-on-battery

or to set the username to a name with a space in it:

option user "a username with spaces"

Using the Online Help

The socket interface has a built-in help system. This can be accessed by telneting to the client's port and running the help command. This will dump a help screen organized into sections for all the available commands. You can get help for a specific command like this:

help options

The help lines are organized as follows:

"command" "arguments" Command description

The arguments may also use a special syntax to describe their usage. The symbols of this syntax have the following meaning:

Syntax Meaning
[] Everything between square brackets is optional.
<> Everything between angle brackets is required.
| A bar means or.
... Ellipsis mean the preceding arguments may be repeated.

Setting and Saving Configuration Options

Configuration options can be global or folding slot specific. A previous section showed how to set a single global option. You can set or list one or more options with a single command using options.

List two options:

options user team

List all explicitly set options:

options *

List all options, including those that still have their default values:

options -d

List all options, including those with default values, and options which are unset:

options -a

Set two options:

options user=anonymous team=0

You will notice that these commands all print out the value of these options in a block starting with the word PyON. This is the data format used by the socket interface and is described in a section below. Not all commands that print in this format will say so in their help string.

The options command allows you to view and modify global options only. You can operate on folding slot specific options with the slot-options command:

slot-options 0 user=anonymous team=0

The number 0 is the folding slot id.

No options are actually saved until the save command is run which writes a new config.xml file which will persist through client restarts.

Listing Folding Slot and Work Unit Information

Folding slot and work unit information can be access with the slot-info and queue-info commands. Both of these commands dump their information in PyON format.

Adding Deleting and Modifying Folding Slots

Adding a new folding slot can be done with slot-add <type> [<name>=<value>]... command. Configuration options for the new slot can be provided as well to override general options, but the folding slot type must be provided. Valid folding slot types are uniprocessor or shorter uni, smp and gpu.

For example, adding a uniprocessor slot:

slot-add uniprocessor

Deleting of an existing slot can be done with slot-delete <slot>. Valid folding slot numbers can be obtained with slot-info command.

Note: Live folding slot manipulation does not require a save command to be effective, but if you fail to save configuration then all your folding slot manipulations will get lost after next FAHClient startup.

Parsing PyON Messages

The socket interface uses the PyON messages to return data to the caller. This makes parsing structured data easier and consistent for all commands. It also makes handing automatic updates much easier.

PyON Message Format

PyON messages consist of a header, content and a trailer. The header is PyON <version> <message name>\n. Where <version> is the PyON version number and <message name> is an arbitrarily chosen name that helps to identify the contents that can be expected to follow the header. The message name always consists of only letters, numbers, dash - and underscore _. The trailer is always ---\n. You can always count on both the header and trailer being printed on their own line. In other words, they will always start and with a return character \n.

Detecting PyON Messages

PyON messages can be detected by scanning the socket output for the PyON header and trailer. Whatever is between the header and trailer will be PyON parsable content.

To detect the header scan for the 6 characters \nPyON . To detect the trailer scan for the 5 characters \n---\n. Data outside of the header and trailer should be ignored. These character strings cannot occur in the PyON content because the return character is escaped as \n.

Parsing PyON Content

PyON stands for Python Object Notation. It is a subset of Python's native data language and a subset of JavaScript Object Notation with a few exceptions. PyON differs from JSON two ways. None is used instead of null and boolean values start with an uppercase letter as in Python. E.g. True and False.

Most of the client commands do not use boolean or None/null values so nearly all data returned by the client can be parsed with a JSON parser. JSON parsers are available for many different languages. A list of available parsers can be found at the bottom of json.org

In Python the content can be parsed with the following code:

value = eval(content, {}, {})

Message Processing Examples

The client GUI, FAHControl, is an Open-Source application. The code in fah/Connection.py is a good example of how to access the client's socket interface. You can check out the code with Git using the following commands:

git clone https://github.com/FoldingAtHome/fah-control

TODO add examples of how to processes PyON messages in various languages.

Scheduling Automatic Updates

Rather than polling the client repeatedly for information you can ask the client to send a PyON message when something has changed using the updates command.

The updates command has 5 subcommands:

Subcommand Description
add <id> <rate> <expression> Add a update with id and update rate.
del <id> Delete a update by id.
list List all currently running updates.
clear Delete all updates.
reset Reset all updates.

For example, we can use the add subcommand to get updates of the work queue at a maximum rate of once every 5 seconds with the following command:

updates add 0 5 $queue-info

The expression argument is an expression that will be evaluated at most once every 5 seconds. The command queue-info must be preceded by a $ so that the script interpreter knows it is a command.

We can then add a second update, now with id 1 to get folding slot updates with:

updates add 1 5 $slot-info

Both slot-info and queue-info print PyON messages so we just have to scan for these messages and process they come. You can tell which message is which by its message name.

The FAHControl program uses the following update commands to get it's information from the client:

updates clear
updates add 0 5 $heartbeat
updates add 1 1 $(options <a list of option names> *)
updates add 2 4 $queue-info
updates add 3 1 $slot-info

The expression parameter is one argument so commands, such as options, which take arguments must be wrapped in $(). See the section The Script Interpreter.

Log Updates

Log updates are handled slightly differently than the updates described in the previous section.

The Script Interpreter

When you connect to the client you are accessing the client's internal script interpreter. For the most part, you don't have to worry about the details of this interpreter because connections to the socket interface put in a simple command loop where each entered line is treated as a command expression and evaluated. However, commands and variables can also be evaluated with the $ prefix or with $() for commands with have arguments.

A simple illustration of this processing can be seen using the eval command:

eval queue-info

The above command will just print the string queue-info which may not be what was expected. Whereas the following command will print the results of running the queue-info command.

eval $queue-info

The above command is equivalent to just running the queue-info command directly. The difference is you can do things like this:

eval "My name is $(option user) and my team is $(option team).\n"

Most command arguments are automatically evaluated before they are passed to the command except for a few special commands like if and updates which either conditionally evaluate their arguments or evaluate them later.

The client's internal scripting language is actually fairly powerful but most of this is not needed to use the socket interface but it does explain why commands like updates need the $ and $() syntax around the expressions the evaluate.

Guidelines for Developing a Language Specific API Layer

We will depend on third-party developers to help us create the API layers which hide the difficulties of socket programming for the most popular programming languages. We ask developers of these APIs to follow a few guidelines to help make interfacing to Folding@home clients consistent across various platforms and languages.

  1. Please release all interface APIs under an Open-Source license such as the GPL, BSD or MIT licenses.
  2. Name API functions using the same names used in the socket level interface.
  3. Use a layered approach which separates higher-level functions form those supplied directly by the socket level API.

Client interface layers

The API should allow API users access to all the same functions provided by the socket layer with the same names but with language specific datatypes.

TODO

  • Talk about the PyON scanning and parsing loop and asynchronous message processing (i.e. threads are not necessary).
  • This section of the document should be expanded as a consistent API interface definition is developed.