silacodegenerator 0.3.2.dev0
SiLA2 code generator for Python3
License: MIT
Keywords: SiLA2,codegenerator,lab automation,laboratory,instruments,experiments,evaluation,visualisation,serial interface,robots

SiLA2CodeGenerator
==================

This package supplies a code generator that creates a working server and
client prototype based on feature definition files and a service
description file.

The codegenerator supports the *SiLA2 server/client* developer in two
major tasks:

1. it converts the Feature Description File (FDL/XML) into a Protobuf
   .proto file
2. it generates a completely running SiLA server/client ( in simulation
   mode), where only the real/hardware specific code needs to be
   added/subclassed to the generated prototype code.

s.\ `Tutorial <#codegenerator-demo-and-tutorial>`__ for a fast
introduction

Features
--------

-  .proto file generation out of FeatureDescription Files FDL/XML
-  .proto file compilation
-  complete server/client generation out of a project directory,
   containing a service\_description file (s.hello\_sila\_project)

-  support for Service/Device detection
-  support for Service/Device feature detection
-  switching between simulation and real (hardware) mode (+)
-  default / standard Features (SiLAService, Sim, runcontrol,
   deviceinfo, ...) (+)
-  default error handling (+)
-  sila-python-django support (+)

(+) under development

Installation
------------

To install this library execute the following commands.

.. code:: bash

    pip install -r requirements.txt
    pip install .

This will also install the ``sila2lib`` package, if it is not installed
yet. Since the packages from the ``requirements.txt`` file do no version
check, you will have to run
``pip install --upgrade -r requirements.txt`` to force an upgrade to a
new version.

It is highly recommended to work in the python3 virtual environment
(default proposal of the installer): This ensures that the system Python
setup is not affected. To activate the virtual environment, type

::

    source [venv]/bin/activate

to deactivate it again, simply type (mind: here is no path required)

::

    deactivate

Run
---

The code can be run using the command ``silacodegenerator``. Use
``silacodegenerator --help`` to get an overview over the accepted
arguments. The most common use for Python will be

.. code:: bash

    silacodegenerator --build <path/to/project/dir>

which, creates the .proto files, compiles them to the gRPC libraries and
then builds server, client, servicer and implementation prototypes.

If you're using ``silacodgenerator`` for C++ instead, you want to include
the ``--cpp`` flag in all of your commands. The most common use here will
be

.. code:: bash

    silacodegenerator --cpp --build

which will also create the .proto files from the .sila.xml files. But it
won't compile them using ``protoc``. This will be done later automatically
by CMake. A corresponding CMakeLists.txt file will also be created for you
along with the prototypes for the server, client and feature
implementations.

Templates
---------

A strength of this CodeGenerator is the extensive usage of template
files to generate the prototypes. Templates can be found in the package
source under the ``templates`` directory. To chose which template to
apply, call the code generator with the ``--template <template-name>``
flag.

Available templates are:

-  **run-inline**: Based on the previous implementations. This templates
   generates calls to commands and properties of all features inside a
   ``run()`` method of the client class.
-  **run-method**: For each command call and property the client
   implements its own method, effectively giving easy access to these
   data to a script from the outside. ``run()`` is still used to
   validate the connection to the server and retrieve basic server
   capabilities.
-  **cpp**: The default for C++ projects. This will be automatically
   chosen when the ``--cpp`` flag is given. It's roughly equivalent to
   the python **run-method** version, i.e. each command call and property
   request are implemented as a separate method in the client.

If you want to implement your own template, it is recommended to copy
one existing template and then modify it. To use it during the build
process, run the code generator with the flag
``--template-dir <path/to/template/directory>``, which will overwrite
the ``--template <..>`` flag and use the given directory as template
source instead.

Example
-------

Python
^^^^^^

The examples directory contains the ``hello_sila2_project``. Building
this project with the following command run inside the examples
sub-directory will result in a new directory in the same folder which is
named after the service name from the corresponding service description
file.

.. code:: bash

    .../examples> silacodegenerator --build hello_sila2_project

The new folder should have the following structure

::

    HelloSiLA2
     + meta                             # the meta information, i.e. the FDL, proto
                                        #   and service description file
     + GreetingProvider
       # Additional information
       __init__.py                      # make this folder a python package
       # Implementations of the server, edit those for the actual implementation
       GreetingProvider_real.py         # the prototype for the real case
       GreetingProvider_simulation.py   # the prototype for the simulation case
       # Servicer
       GreetingProvoder_servicer.py     # The servicer that serves as a bridge between the
                                        #   server and the corresponding implementation
         + gRPC
          __init__.py                   # make this folder a python package
          # The auto-generated stub files.
          #     Do not Edit!
          GreetingProvider_pb2.py
          GreetingProvider_pb2-grpc.py

C++
^^^

Similarly, sila_cpp also implements the HelloSiLA2 example. Run
the codegenerator inside this directory with the following command

.. code:: bash

    .../examples> silacodegenerator --cpp --build HelloSiLA2

This will result in a folder having the following structure

::

    HelloSiLA2
      + meta                            # the meta information, i.e. the FDL
                                        #   and .proto files
      # project files
      + CMakeLists.txt                  # a running CMake project
      + HelloSila2.qrc                  # resource file used for compiling the
                                        # FDL files into the server binary
      + GreetingProvider
      # header and source file for the GreetingProvider Feature
        + GreetingProviderImpl.h
        + GreetingProviderImpl.cpp
      + TemperatureController           # same for the TemperatureController
        + TemperatureControllerImpl.h
        + TemperatureControllerImpl.cpp
      # Client and Server prototypes
      + HelloSiLA2Client.cpp
      + HelloSiLA2Server.cpp

Proto file generation
---------------------

If you only want to convert a SiLA2 Feature Description File (FDL) into a .proto file:

::

    silacodegenerator [feature_descripton_file.xml]

This will result in a proto file with the output filename
feature\_descripton\_file.proto

The output proto filename can be set with the -p option.

Example:

::

    python3 silacodegenerator.py -f [feature_descripton_file.xml] -p my_protofilename.proto

Testing
-------

          To validate that the basic machinery is working correctly, please run
          the unittests:

          ::

              cd [dir of codegenerator]

              python -m unittest

Notes
-----

-  While in prior implementations the change between Simulation and Real
   mode relied on the Server and the ``inject_implementation()`` method
   of the servicer, this is now complete the responsibility of the
   servicer. It thus accepts the ``simulation_mode`` parameter at
   initialisation, and will thus either load the ``<Feature>Simulation``
   or ``<Feature>Real`` implementation.