PyAnsys Protos Generator Packaging Tool
=======================================

This package allows you to automatically generate a python package
from proto files stored according to gRPC proto file conventions.

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

Install the python packaging tool with:

.. code::

   pip install ansys-tools-protos-generator


Usage
-----
Once installed, this package can be run directly from the command line with:

.. code::

   python -m ansys.tools.protos_generator <directory-containing-protosfiles>

The ``protos-samples`` directory contains a simple sample service
containing the following directory structure.

::

   ─ansys
   │   ├───api
   │   │   ├───sample
   │   │   │   ├───v1
   │   │   │   │   ├───sample.proto
   │   │   │   │   └───VERSION

Running:

.. code::

   python -m ansys.tools.protos_generator ansys/api/sample-example/v1

Will generate the following python package:

::

   dist/ansys-api-sample-v1-0.5.3.tar.gz

This package can then be installed via:

.. code::

   pip install dist/ansys-api-sample-v1-0.5.3.tar.gz

Or uploaded to pypi with:

.. code::

   twine upload dist/ansys-api-sample-v1-0.5.3.tar.gz

Contact alexander.kaszynski@ansys.com for the token and credentials to
upload to pypi under the pyansys account.


Non-Default Directory
~~~~~~~~~~~~~~~~~~~~~
You can change the default directory to a non-default directory with:

.. code::

   python -m ansys.tools.protos_generator <protosfiles_path> <outdir>

For more details, run:

.. code::

   python -m ansys.tools.protos_generator -h


Run from within Python
~~~~~~~~~~~~~~~~~~~~~~

You can run this within python with:

.. code:: python

   from ansys.tools.protos_generator.generator import package_protos
   protosfiles_path = 'proto-samples/ansys/api/sample/v1/'
   outdir = 'C:/tmp'  # or Linux: '/tmp'
   dist_file = package_protos(protosfiles_path, outdir)


Ansys gRPC Directory Structure - Standards
------------------------------------------

In the gRPC proto file naming and directory convention see (`gRPC
standards <https://grpc.io/docs/>`__), each module is placed in a
directory tree that contains the origin of the module.  The origin of
all modules should be ``ansys``, followed by ``api``, followed by
``<product/service>``.

For example

::

   ─ansys
   │   ├───api
   │   │   ├───<product/service>
   │   │   │   ├───v1
   │   │   │   │   └───service.proto
   │   │   │   │   └───other_service.proto
   │   │   │   │   └───VERSION

This convention follows the `gRPC standards <https://grpc.io/docs/>`__
except for the ``VERSION`` file containing a single `semantic version
<https://semver.org/>`_ string.  Due to the complexity of Ansys
services, the ``vX`` version cannot be used to fully describe state of
the version of the service.  For example, if the service were to add a
single message to a service, we need a way of tracking that in the
version of our auto-generated gRPC interface files and packages.  Hence
a semantic version.

There are other advantages to having a semantic version, namely that
python packages containing the autogenerated gRPC interface files will
also have this version.  This will give any downstream dependencies
the ability to depend on a compatible API.  For example, if higher
level package requires a certain version of autogenerated gRPC
package:

::

   ansys.<product>.<feature>==0.2.0 depends on ansys.api.<product>.v1==0.8.0
   ansys.<product>.<feature>==0.3.0 depends on ansys.api.<product>.v1==0.9.0

This way, you can maintain backwards compatibility with various
versions of a product for the entire dependency chain without
encountering forwards/backwards compatibility issues.

Note that we still use ``vX``.  This is required by Google gRPC APIs
and affords us the ability to expose two APIs similtaniously from a
gRPC service.  For example, both a ``v1`` and ``v2`` could be exposed
similtaniously from a service, each with their own semantic version to
describe the granular state of that API.

This will be handled manually by creating a new directory containing
the next version of the API you choose to expose.

::

   ─ansys
   │   ├───api
   │   │   ├───sample
   │   │   │   ├───v1
   │   │   │   │   ├───sample.proto
   │   │   │   │   └───VERSION
   │   │   │   ├───v2
   │   │   │   │   ├───sample.proto
   │   │   │   │   └───VERSION


For all other questions regarding gRPC standards, please reference
`gRPC Documentation <https://grpc.io/docs/>`__, `gRPC Motivation and
Design Principles <https://grpc.io/blog/principles/>`_, and `API
Design Guide <https://cloud.google.com/apis/design>`_.


Development
-----------
Run unit testing with:

.. code::

   git clone https://github.com/pyansys/pyansys-protos-generator.git
   cd pyansys-protos-generator
   pip install -e .
   pip install requirements_test.txt
   pytest -v
