gen_proto.py - generate a protocol from a specification

Overview

The gen_proto.py script takes a JSON document specifying your protocol and combines it with a template to produce a custom python module implementing your protocol.

You simply specify the message types, message type IDs and the expected fields for each message type.

Usage

Autogenerate a python module that implements a custom protocol

usage: gen_proto.py [-h] -s SPECFILE [-t TEMPLATE] [-o OUTPUT]
Options:
-s, --specfile The specification file to use
-t, --template The location of the templates directory to use
-o=generated.py, --output=generated.py
 Where to write output

JSON specification format

gen_proto.py builds modules from JSON specifications files, for examples see tools/examples/ where you will find a small selection of example protocols.

Each specification file consists of a JSON dictionary containing the following fields:

Field name Data type Description
protocol_name string The name for your protocol
imports list List of python modules to import into the generated module
protocol_sock string Full name of the socket class to base your protocol on
named_fields boolean If true, the handler methods expect a dict
mixins list List of other classes to inherit from (i.e mixins)
messages list List of dictionary objects, see below

Within the messages field you must provide a list of dictionary objects with the following fields:

Field name Data type Description
msg_type_str string A string representing this message type, will become python identifier
msg_type_int integer Numeric ID of this message type
fields list A list of strings giving field names in this message type

After generating your module, you can import it and subclass it to implement the handlers, each handler function will be passed the fields from the message.

It is then up to you to either implement parse_msg() or add one of the mixins and finish off your protocol.

Examples

These examples can be run from the command line:

python -m socktools.tools.examples.gen_proto.build_example_chat

Python API

This module is intended to be run as a command-line tool primarily, though a python API is also available.

socktools.tools.gen_proto.get_default_template_path()[source]

Calculates the default templates path

This function is provided as a convenience for users of the Python API, such as build_example_chat.py

Returns:The default templates path
Return type:str
socktools.tools.gen_proto.get_parser()[source]

Get a command-line parser for this tool

This function simply returns a parser object from argparse, it is here only to make generating documentation simpler.

Returns:The populated argument parser
Return type:argparse.ArgumentParser
socktools.tools.gen_proto.get_template_vars(specdata, filename)[source]

Get the template variables and their default values

Evaluates the data from a specification file and uses it to build a dict of variables and their substitution values.

Parameters:
  • specdata (dict) – The toplevel object from the specification file as loaded from load_json_file()
  • filename (str) – The absolute path to the specification file
Returns:

A dict mapping %%VARIABLE%% tokens to the strings they should be replaced with

Return type:

dict

socktools.tools.gen_proto.load_json_file(path)[source]

Load and parse a JSON file

Loads a JSON file from disk and attempts to parse it at the same time - a simple convenience wrapper around json.load(). No exception handling is done, it is up to the caller to wrap in a try block if required.

Parameters:path (str) – Path to the JSON file needing to be loaded, this should usually be an absolute path
Returns:The toplevel object parsed from the file, usually this is a dict or a list
Return type:object.object
socktools.tools.gen_proto.load_template(path, template_name)[source]

Load a single template

Loads a single template file into memory, like load_json_file() this is primarily a simple convenience wrapper that handles opening and reading the full contents of a file. No exception handling is done, it is up to the caller to wrap in a try block if required.

Parameters:
  • path (str) – The path to the directory containing the template file
  • template_name (str) – The name of the template to load
Returns:

The contents of the template file, in future this might be some sort of template object instead

Return type:

str

socktools.tools.gen_proto.load_templates(path)[source]

Loads default templates

A simple wrapper around load_template that loads all the default templates needed

Parameters:path (str) – The absolute path to the templates directory
Returns:A dict mapping the template name to the contents
Return type:dict
socktools.tools.gen_proto.render_module(specfile_path, template_path, output_path)[source]

Renders the generated python module

This is where the real work happens - this function loads the specification file and templates then renders the module and writes it to disk.

Parameters:
  • specfile_path (str) – Absolute path to the specification file
  • template_path (str) – Absolute path to the templates directory
  • output_path (str) – Absolute path to the output file to create