Package: saw-client
SAW Python ClientIn-development Python client for SAW. Currently tested on Linux and MacOS -- at present there may be some minor issues running the Python Client in a Windows environment that needs addressed (e.g., some Python process management methods are not cross-OS-compatible).This SAW client depends on thesaw-remote-apiserver.TL;DR Steps to running SAW Python scriptsClone the repogit clone https://github.com/GaloisInc/saw-script.gitEnter the repocd saw-scriptInitialize git submodulesgit submodule update --initNavigate to the python clientcd saw-remote-api/pythonInstall and setup some version of thesaw-remote-apiserver and update any
relevant environment variables as needed (seesaw_client.connect()documentation
for the various ways a server can be connected to).
E.g., here is how the docker image of the server might be used:$ docker run --name=saw-remote-api -d \
  -v $PWD/tests/saw/test-files:/home/saw/tests/saw/test-files \
  -p 8080:8080 \
  galoisinc/saw-remote-api:nightly
$ export SAW_SERVER_URL="http://localhost:8080/"Install the Python client (requires Python v3.8 or newer -- we recommend usingpoetryto install the package):$ poetry installRun tests or individual scripts:$ poetry run python -m unittest discover tests/saw
$ poetry run python tests/saw/test_salsa20.py(We're aware the tests currently emit someResourceWarnings regarding
subprocesses when run viaunittesteven though they pass and successfully
verify the goals. It's on our to-do list.)Python Client Installation (via Poetry)First, clone the repository and submodules.$ git clone https://github.com/GaloisInc/saw-script.git
$ cd saw-script
$ git submodule update --initThen, usepoetryto install
the python client from thesaw-remote-api/pythondirectory:$ cd saw-remote-api/python
$ poetry installSAW serverTo run the verification scripts asaw-remote-apiserver must be available,
either as a local executable or running in docker image listening on a port.Connecting with a server in a scriptConnecting to a server in a Python script is accomplished via thesaw_client.connectmethod. Its accompanying Python doc strings describe the various ways it can be
used. Below is a brief summary:saw_client.connect(), when provided no arguments, will attempt the following in order:If the environment variableSAW_SERVERis set and refers to an
executable, it is assumed to be asaw-remote-apiexecutable and will be
used for the duration of the script.If the environment variableSAW_SERVER_URLis set, it is assumed to be
the URL for a running SAW server inhttpmode and will be connected to.
(N.B., this can be a local server or a server running in a docker image.)If an executablesaw-remote-apiis available on thePATHit is
assumed to be a SAW server and will be used for the duration of the script.Additional arguments and options are documented with the function.Notable, thereset_serverkeyword can be used to connect to a running server
and reset it, ensuring states from previous scrips have been cleared. E.g.,saw_client.connect(reset_server=True).Acquiring a SAW ServerThere are several ways a server executable can be obtained.Server executablesAn executable of the server is included in the SAW release/nightly tarballs.If using a SAWrelease, it
is recommended to usev0.8or greater if possible. (v0.7doesinclude the
server and may work for individual use cases, but running repeated scripts
against the same persistent server will not work as intended.)Nightly server builds can be found asArtifactsof theNightly
Buildsgithub action. I.e., go to theNightly BuildsGithub Action, click on a
successful build, scroll to the bottom and underArtifactsa Linux, Windows,
and MacOS tarball will be listed. (Apologies... we need to make these easier to
find...)Server docker imagesDocker images for the SAW server are currently uploaded toDockerHub.These images are set up to run as HTTPsaw-remote-apiservers, e.g.:docker run --name=saw-remote-api -d \
  -p 8080:8080 \
  galoisinc/saw-remote-api:TAG(whereTAGis eitherlatestornightly) will launch a server listening athttp://localhost:8080/. (As of March 2020,nightlyis recommended, as the
server in the last official release (i.e., the one accompanying SAWv0.7)
contains some non-trivial bugs that greatly limit its utility.)The-voption todocker runcan be used to load files into the docker
server's working directory so they can be loaded into the server at the request
of python scripts. E.g.,-v PATH_TO_FILES:/home/saw/files/will upload the
contents of the host machine's directoryPATH_TO_FILESto the/home/saw/files/directory in the docker container, which corresponds to the
relative pathfiles/for the SAW server. (If desired, it can be useful to
place files in a location in the Docker container such that the same relative
paths in scripts refer to the same files in the host machine and docker
container.)Building from SourceIf this repository is checked out and the build directions are successfully run,cabal v2-exec which saw-remote-apishould indicate where the server executable has
been stored bycabal.Alternativelycabal v2-install saw-remote-apishould install the server
executable into the user's~/.cabal/bindirectory (or similar), which (if
configured properly) should then appear assaw-remote-apiin a user'sPATH.Running Python SAW verification scriptsOnce the server is setup and any path variables are setup as desired, the
Python (>= v3.8) client can be installed usingpoetryas follows:$ cd saw-remote-api/python
$ poetry installThen the tests or individual scripts can be run as follows:$ poetry run python -m unittest discover tests/saw
$ poetry run python tests/saw/test_salsa20.pyIf leveraging environment variables is undesirable, the scripts themselves can
specify a command to launch the server, e.g.:saw_client.connect(COMMAND)whereCOMMANDis a command to launch a new SAW server in socket mode.Or a server URL can be specified directly in the script, e.g.:saw_client.connect(url=URL)whereURLis a URL for a running SAW server in HTTP mode.Running Verification Scripts from a clean stateTo ensure any previous server state is cleared when running a SAW Python script
against a persistent server (e.g., one running in HTTP mode in a different process),
thereset_serverkeyword can be passed tosaw_client.connect(). E.g.,saw_client.connect(url="http://localhost:8080/", reset_server=True)will connect to a SAW server running athttp://localhost:8080/and will
guarantee any previous state on the server is cleared.