Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

To create proto classes, do the following:

  1. Get proto files from Technical Support.
  2. Save the script as a PY file.

    Expand
    titleClick to expand...


    Code Block
    import os
    import shutil
    import inspect
    import pkg_resources
    
    from grpc_tools.protoc import main as protoc
    
    POSIX_SEP = '/'
    
    
    def paths_print(items):
        print("Paths:")
        print("-"*80)
        for k, v in items:
            print("\t", k, "\t\t", v)
        print("-"*80)
    
    
    def clear_folder(output_dir):
        if os.path.exists(output_dir):
            shutil.rmtree(output_dir)
    
    
    def generate_bindings(protos_dir, axxonsoft_protos_dir):
        proto_files_relative = get_proto_files_relpath(axxonsoft_protos_dir, protos_dir)
    
        protoc_keys = [
            f'-I{protos_dir}',
            '--python_out=.',
            '--grpc_python_out=.',
        ]
        protoc_args = protoc_keys + proto_files_relative
    
        is_protoc_patched = 'include_module_proto' in inspect.getfullargspec(protoc).args
        if not is_protoc_patched:
            protoc_args_patch_start = [inspect.getfile(protoc)]
            protoc_args_patch_end = [f'-I{pkg_resources.resource_filename("grpc_tools", "_proto")}']
        else:
            protoc_args_patch_start = protoc_args_patch_end = []
    
        print('Call of "protoc":')
        protoc_retcode = protoc(protoc_args_patch_start + protoc_args + protoc_args_patch_end)
        # print(f'\targs = {protoc_args}\n\tretcode = {protoc_retcode}\n')
        return protoc_retcode
    
    
    def generate_init_py_files(bindings_output_dir):
    
        def make_init_py_subtree(base_path):
            # print('\tprocess {!r}'.format(base_path))
            make_init_py(base_path)
            for subdir in get_subdirs(base_path):
                make_init_py_subtree(subdir)
    
        def make_init_py(base_path):
            modules = get_py_modules(base_path)
            init_py_path = os.path.join(base_path, '__init__.py')
            with open(init_py_path, 'w') as init_py:
                init_py.write('# Generated AUTOMATICALLY by \"{}\".\n'.format(os.path.basename(__file__)))
                init_py.write('# DO NOT EDIT manually!\n\n')
                for m in modules:
                    if '.Internal' not in m:
                        init_py.write('from . import {!s}\n'.format(m))
    
        def get_subdirs(base_path):
            _, subdirs, _ = next(os.walk(base_path))
            return [os.path.abspath(os.path.join(base_path, s)) for s in subdirs]
    
        def get_py_modules(base_path):
            _, subdirs, files = next(os.walk(base_path))
            file_modules = [f.rstrip('.py') for f in files if f.endswith('.py') and f != '__init__.py']
            return subdirs + file_modules
    
        # print('Generate "__init__.py" files:')
        make_init_py_subtree(bindings_output_dir)
    
    
    def get_proto_files_relpath(axxonsoft_protos_dir, protos_dir):
        out = []
        for root, dirs, files in os.walk(axxonsoft_protos_dir):
            for file in files:
                if file.endswith(".proto") and ".Internal" not in file:
                    full_path = os.path.abspath(os.path.join(root, file))
                    rel_path = os.path.relpath(full_path, protos_dir)
                    posix_rel_path = rel_path.replace(os.sep, POSIX_SEP)
                    out.append(posix_rel_path)
        return out
    
    
    def run_generate():
    
        protos_dir_name = 'grpc-proto-files'
        AxxonSoft_dir_name = 'AxxonSoft'
    
        current_dir = os.path.dirname(os.path.abspath(__file__))
        protos_dir = os.path.join(current_dir, protos_dir_name)
        axxonsoft_protos_dir = os.path.join(protos_dir, AxxonSoft_dir_name)
        bindings_package_dir = os.path.join(current_dir, AxxonSoft_dir_name)
        paths_print([
            ('protos_dir', protos_dir),
            ('axxonsoft_protos_dir', axxonsoft_protos_dir),
            ('bindings_package_dir', bindings_package_dir),
        ])
    
        clear_folder(bindings_package_dir)
        code = generate_bindings(protos_dir, axxonsoft_protos_dir)
        if code == 0:
            generate_init_py_files(bindings_package_dir)
    
        return code
    
    
    if __name__ == '__main__':
        print('Axxon One NativeBL bindings generator.')
        print('To generate that bindings you need to copy to `grpc-proto-files` folder: ')
        print('1) `AxxonSoft` folder with AxxonSoft proto-files, ')
        print('2) `google` folder with Google common proto-files.')
        result = run_generate()
        if result == 0:
            print('Bindings generation was completed successfully')
        else:
            print(f'An error occurred while generating bindings: {result}')



  3. Create the grpc-proto-files folder in the script folder. Place the AxxonSoft and google folders in this folder along with their contents from the resulting archive with proto files.
  4. Run the script.

...