Skip to main content
Configuring CLI with Protobuf and Python
20 Oct 2020

Configuring CLI with Protobuf and Python

Many of us may think that the easiest way to interact with computers is through a teeny-tiny device; we all know as a mouse. However, we programmers love to use another one. Even before the mouse came into the picture, the interaction between people and operating systems happened with a keyboard where the user typed commands to instruct machines to do things. The easiest way to give these commands is through the Command Line Interface (CLI). CLI is a text-based user interface that you can use to view and manage computer files and programs. Usually, the CLI features a black box with white text. Nowadays, many users choose to use the graphical user interface (GUI) compatible with operating systems like Windows, Linux, and Mac. The best examples of CLIs are the MS-DOS operating system and the Windows operating system's command shell. Even programming languages like Python supports the CLIs. And that is exactly what this blog is about.

In this blog, I will try to explain an easy way to configure CLI with protobuf using the Python language. But before the actual process, here is some general trivia:

What is protobuf?

Protobuf, popularly known as Protocol Buffers, is developed by Google. It is Google's language-neutral, platform-neutral, and binary encoding format that helps create an outline for data. You can use a specially generated source code once you figure out to structure your data. This generated source code allows you to write and read your structured data easily. You can do it from various data streams by using different languages. The structure of protobuf looks something like this:

message Employee {

  required int32 id = 1;

  required string name = 2;

  optional string email = 3;

}

You can implement the Protocol Buffers specifications in many languages. It supports all the leading languages, such as Java, C, Go, etc. Protobuf compiles files from a specified directory to generate output files. The compiler reads the files as src/foo.proto and src/bar/baz.proto, which are the protobuf files extensions. It produces two output files that are build/gen/foo_pb2.py and build/gen/bar/baz_pb2.py. The compiler also creates the build/gen/bar automatically if required, but it won't create build or build/gen as they should exist already.

Note that if the .proto file or its path contains any characters which cannot be used in Python module names, like hyphens, they will be replaced with underscores. E.g., the file foo-bar.proto becomes the Python file foo_bar_pb2.py. To know more about Python protobuf you can visit protobuf docs by Google developers here.

What is Python?

Now, everyone reading this must be aware of what Python is. However, here is some necessary information. Python is an object-oriented programming language used to develop web applications, workflow creation, read and modify files, handle big data, and perform complex mathematical operations and system scripting. It is one of the popular languages for Rapid Application Development because of its ability to offer dynamic typing and dynamic binding options. Now, let's find out the relationship between Python and Cmd2 Library.

Cmd2 Library

Cmd2 is a tool that is popular amongst developers to build an interactive command-line application in Python. It is rich in features and a highly user-friendly tool that makes it easy for developers to build command-line applications quickly. Cmd2 offers a straightforward and basic API that is an extension of Python's built-in cmd module.

Now let’s see the procedure to configure CLI using protobuf. But first, the installations:

  • Python
    apt-get install python
  • Cmd2 Library

    Install using pip

    pip install cmd2
  • Protobuf

    Install using pip

    pip install protobuf

Please make sure you install the software by checking for the supported versions.

The next step is the Proto parsing. It creates a protobuf tree for referring objects in CLI for auto-completion as given below:

First, create a protobuf tree by parsing proto directory where all the .proto files are located. Parse all the protobuf files in the directory and create a dictionary of Enums, protobuf messages, and a file map to import & protobuf objects.

  
{ 
 “”: {  
“objs” :  [ list of enum descriptor ] + [ list of message descriptor], 
“imports”: [ list of imports ]  
      } 
}
 

After generating a dictionary, create a graph for nodes, which is also a dictionary that maintains a parent-child relationship for accessing nodes in an orderly fashion. It all depends on how you define your model schema and how you want it to process.

There is a lot you can write about Protocol Buffers parsing. I will try to cover the parse Protocol Buffers in detail in my next blog. Now, let’s see a use case for protobuf.

Use case for protobuf:

The most common practical use case for protobuf would be the big projects where you have complex modeling structure and need better performance. Protobuf supports backward compatibility, which helps the deprecating field, as you don't need to change the model schema. Instead, you have to add a deprecated_in flag.

You can define custom API specifications in YAML format and add to the above schema for future use.
e.g.

resource:

     ‹pb_name>:

         resource _uri : <api> actions:

               - action: show

                     cli_path: show <obj_name>

Now, you are done with protobuf parsing and created resources that you can use in CLI. Here, onwards you can use cmd2 lib functions.

Procedure for CLI invocation:

Invoke base class Cmd from cmd2 lib by using a custom implementation. You can customize implementation by inheriting this class and override methods of cmd class too.

Import cmd from cmd2

app =  Cmd(  )

app.cmdloop()

 

The output will look like this:

[root user]:>


Cmdloop will invoke a CLI prompt repeatedly. This will even do a set of tasks like accepting user input, parsing initial prefixes for autocompleting a command, and dispatching to specific action methods.

Cmd2 library provides inbuilt functions like show, no, where, etc. Any command that you execute on CLI started using cmd2 is mapped to a method that begins with do_(). e.g., If you run the show command, then it will invoke do_show()

If the command executed by the user is not mapped with any of the do commands, then it will call a function named default() in cmd. You can refer official cmd2 library doc or go to your environment, and under site-packages, you will see cmd2.py. Integrating it with protobuf will increase the performance of CLI at times while accessing models.

That's it! Your CLI configuration process is complete. If you wish to take this to the next level, then all you have to do is implement an auto-completion of the CLI command just by fetching the protobuf tree. That's all for now. As I have mentioned earlier, I will write in detail about the parse Protocol Buffers and CLI in my upcoming blog. Till then, try this CLI config process. Share your queries or suggestions in the comments section; happy coding!

Subscribe to our feed

select webform