grpc

This is the ANSA GRPC module.

AnsaClient

class lasso.ansa.grpc.AnsaClient(stub: lasso.ansa.grpc.AnsaGRPC_pb2_grpc.LassoAnsaDriverStub)

Create an AnsaClient for remote scripting

Parameters
stubAnsaGRPC_pb2_grpc.LassoAnsaDriverStub

grpc stub from connection

Examples

Please see the docs or the script: ‘lasso/ansa/grpc/example_client.py’

Methods

run(self, function_name, \*args, \*\*kwargs)

Run an arbitrary ANSA function

shutdown(self)

shut down the remote server

__init__(self, stub: lasso.ansa.grpc.AnsaGRPC_pb2_grpc.LassoAnsaDriverStub)

Create an AnsaClient for remote scripting

Parameters
stubAnsaGRPC_pb2_grpc.LassoAnsaDriverStub

grpc stub from connection

Examples

Please see the docs or the script: ‘lasso/ansa/grpc/example_client.py’

run(self, function_name, *args, **kwargs) → object

Run an arbitrary ANSA function

Parameters
function_namestr

full module path of the ansa function to call as string

*argsobject

arguments passed to function in ANSA

**kwargsobject

named arguments passed to function in ANSA

Returns
anythingobject

whatever ANSA returns

Examples

>>> entity = client.run("ansa.base.CreateEntity", 1, "POINT")
>>> client.run("ansa.base.SetEntityCardValues",
>>>     deck=1,
>>>     entity=entity,
>>>     fields={
>>>         "X": 4
>>>     })
shutdown(self)

shut down the remote server

What is RPC?

Remote Procedure Call (RPC) is used to call a function on another process often on another machine. The remote process might additionaly be implemented in a different programming language. The compatability is ensured by using an interface definition file with a library-specific syntax. From this interface file client implementations can be generated for other programming languages automatically. The generated code for servers though requires the user to implement of course the function calls himself. Since we already implemented the ANSA server though, there is no need to do this.

Then what is GRPC?

While RPC is the principle, GRPC is an implementation from Google.

What data exchange format is used?

The exchange format is Protobuf, which is a binary format. The exchangable datatypes are usually specified in an interface file (.proto) and this file can be used to generate code for many different languages. Proto files can also be composed from JSON. For being binary, its ‘relatively’ fast though there is better juice out there but also often more complicated or less well supported.

If RPC is generic, why can only another Python connect to ANSA RPC?

Because we are lazy. We simply send Python binary data objects (pickled) by using grpc. We could generalize it, but we didn’t require it yet. Also generalization requires some effort.

How to install the requirements for a server?

The installation of all requirements is unfortunately quite difficult since ANSA is stuck at python 3.3 which requires several tricks.

  1. Download and install Anaconda Python.

  2. Create a python 3.3 environment.

    conda create -n py33 python=3.3
    
  3. Activate the environment

    conda activate py33
    
  4. Install requirement enum34

    python -m pip install enum34
    
  5. Install requirement protobuf and protobuf3

    conda install protobuf protobuf3
    
  6. Install grpc

    Clone the repo:

    git clone -b v1.20.0 https://github.com/grpc/grpc
    cd grpc
    

    Clone the required submodules:

    git submodules update --init --recursive
    

    Edit the file setup.py as follows:

    INSTALL_REQUIRES = (
        "six>=1.5.2",
        # "futures>=2.2.0; python_version<'3.2'",
        "futures>=2.2.0",
        # "enum34>=1.0.4; python_version<'3.4'",
        "enum34>=1.0.4",
    )
    

    Run the installation:

    python setup.py install
    

    Warning

    The compilation may require certain system libraries to be installed already.

How to start the service?

The entire package is wrapped as a command-line utility. The service info can be called as follows:

> python -m lasso.ansa.grpc.server --help

usage: server.py [-h] [--ansa-filepath ANSA_FILEPATH]
                [--python33-path PYTHON33_PATH] [--port PORT]
                [--interactive INTERACTIVE] [--show-gui SHOW_GUI]
                [--enable-logging ENABLE_LOGGING]

GRPC Server for ANSA Remote Scripting from LASSO GmbH
-----------------------------------------------------

optional arguments:
-h, --help            show this help message and exit
--ansa-filepath ANSA_FILEPATH
                        Filepath to ANSA.
--python33-path PYTHON33_PATH
                        Path to the python 3.3 installation whose site-
                        packages contains packages for ANSA.
--port PORT           Port on which the remote scripting will be served.
--interactive INTERACTIVE
                        Whether to run the server in interactive mode.
--show-gui SHOW_GUI   Whether to show a gui or run in batch mode only.
--enable-logging ENABLE_LOGGING
                        Whether to actively log activities to the console.

The arguments are:

  • --ansa-filepath ansa command or path to the executable

  • --python33-path path to a python 3.3 installation holding required modules for ansa

  • --port to run the service on

  • --interactive enables an interactive command line shell on the server

  • --show-gui enable the gui, causes usually trouble, believe me

  • --enable-logging display server actions in the command line

> python -m lasso.ansa.grpc.server
    --ansa-filepath ansa
    --python33-path ~/sw/anaconda3/envs/py33/

[/] Running: ansa -nolauncher -nogui -execscript
    ~/programming/python/lasso-python/lasso/ansa/grpc/server_ansa.py
    -execpy "serve(16135,False,False)"

DISPLAY=:0.0

... ANSA stuff ...

Generating code...
Code generation completed.

    ANSA Remote Scripting Server by LASSO GmbH
    ------------------------------------------

How to test the connection?

You can test the connection by opening an interactive python shell with a connected client as follows (address is optional):

> python -m lasso.ansa.grpc.client --address localhost:16135

    ANSA Remote Scripting Client by LASSO GmbH
    ------------------------------------------

Python 3.7.0 (default, Jun 28 2018, 13:15:42)
[GCC 7.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
> client.run("ansa.base.CreateEntity", deck=1, element_type="POINT")
<Entity: 0x7f1240e8ac18 type: POINT id:1>
> client.shutdown()

The client has the method called client.run and works similar to the REST API. All arguments entered behind the function name are forwarded to ANSA on the other side. The entity object returned can be used for further calls. The server (not client!) can be shut down with client.shutdown().

How to connect from a script?

This example script is located at lasso/ansa/grpc/example_client.py.

import grpc
from lasso.ansa.grpc import (
    LassoAnsaDriverStub,
    AnsaClient,
    get_grpc_connection_options,
)

# important
address = "localhost:16135"
options = get_grpc_connection_options()

# open channel
with grpc.insecure_channel(address, options) as channel:
    stub = LassoAnsaDriverStub(channel)

    # create client
    client = AnsaClient(stub)

    # do the thing
    entity = client.run("ansa.base.CreateEntity",
                        deck=1,
                        element_type="POINT")

    client.run("ansa.base.SetEntityCardValues",
            deck=1,
            entity=entity,
            fields={
                "X": 4
            })

The options ensure that the low default memory limit is raised. Also the channel needs to be opened and managed by the user due to pythons IO and memory management. In consequence it would not make sense to open the channel hidden within the AnsaClient.

I’m having trouble when enabling the GUI

Yeah, we sometimes have too. It depends on several factors. Simply leave it closed.

How to shut down the service?

Either hit Ctrl+C in the command line or run client.shutdown(). Ctrl+C may occasionally cause ANSA to dump crash while terminating for an unknown reason (possibly multithreading). We are happy for hints.

Seems awfully complex, can you make it simpler?

Maybe, but we already hide stuff we shouldn’t so I guess it’s ok for the moment.