multicast

Submodules

Package Contents

Classes

mtool

Class for Multicast tools.

Data

__all__

__path__

The sequence of strings enumerating the locations where the package’s submodules will be found.

__package__

The package of this program.

__module__

The module of this program.

__name__

The name of this program.

__version__

The version of this program.

__prologue__

The one-line description or summary of this program.

__doc__

_MCAST_DEFAULT_BUFFER_SIZE

Arbitrary buffer size to use by default, though any value below 65507 should work.

_MCAST_DEFAULT_PORT

Arbitrary port to use by default, though any dynamic and free port would work.

_MCAST_DEFAULT_GROUP

Arbitrary group to use by default, though any mcst grp would work.

_MCAST_DEFAULT_TTL

Arbitrary TTL time to live to use by default, though any small (1-126) TTL would work.

_BLANK

Arbitrary blank string.

EXIT_CODES

See multicast.exceptions.EXIT_CODES.

EXCEPTION_EXIT_CODES

See multicast.exceptions.EXCEPTION_EXIT_CODES.

CommandExecutionError

See multicast.exceptions.CommandExecutionError Class.

ShutdownCommandReceived

See multicast.exceptions.ShutdownCommandReceived Class.

get_exit_code_from_exception

See multicast.exceptions.get_exit_code_from_exception function.

exit_on_exception

See multicast.exceptions.exit_on_exception function.

genSocket

See multicast.skt.genSocket.

endSocket

See multicast.skt.endSocket.

API

multicast.__all__[source]

[’package’, ‘module’, ‘name’, ‘version’, ‘prologue’, ‘doc’, ‘exceptions’, ‘e…

multicast.__path__[source]

None

The sequence of strings enumerating the locations where the package’s submodules will be found.

The __path__ attribute, like many dunder attributes, is associated with the implementation of Python language features. When utilizing this module as an imported module or a command-line interface (CLI) tool, the __path__ attribute can be safely disregarded.

Minimal Acceptance Testing:

First set up test fixtures by importing multicast.

    >>> import multicast as _multicast
    >>>

    >>> _multicast.__path__ is not None
    True
    >>>

Testcase 0: multicast.path should be a list. A: Test that the path attribute is initialized. B: Test that the path attribute has contents. C: Test that the path attribute has a value of “multicast” somewhere in the first item.

    >>> _multicast.__path__ is not None
    True
    >>> type(_multicast.__path__)
    <class 'list'>
    >>> _multicast.__name__ in _multicast.__path__[0]
    True
    >>>
multicast.__package__[source]

‘multicast’

The package of this program.

The __package__ attribute, like many dunder attributes, was associated with the implementation of Python language features. When utilizing this module as an imported module or a command-line interface (CLI) tool, the __package__ attribute can be safely disregarded. Within the context of this module, __package__ serves as a convenient constant that holds the name of the package.

Minimal Acceptance Testing:

First set up test fixtures by importing multicast.

    >>> import multicast as _multicast
    >>>

    >>> _multicast.__package__ is not None
    True
    >>>

Testcase 0: multicast.package should be the string “multicast”. A: Test that the package attribute is initialized. B: Test that the package attribute is a string. C: Test that the package attribute has a value of “multicast”.

    >>> _multicast.__package__ is not None
    True
    >>> type(_multicast.__package__) == type(str())
    True
    >>> type(_multicast.__package__)
    <class 'str'>
    >>> _multicast.__package__
    "multicast"
    >>>
multicast.__module__[source]

‘multicast’

The module of this program.

The __module__ attribute, like many dunder attributes, is associated with the implementation of Python language features. When utilizing this module as an imported module or a command-line interface (CLI) tool, the __module__ attribute can be safely disregarded. Within the context of this module, __module__ serves as a convenient constant that holds the name of the module.

Out of the three attributes: package, module, and name, it is recommended that module be used to programmatically obtain the value for comparative purposes, as it is specifically suited for that function.

Minimal Acceptance Testing:

First set up test fixtures by importing multicast.

    >>> import multicast as _multicast
    >>>

    >>> _multicast.__module__ is not None
    True
    >>>

Testcase 0: multicast.module should be the string “multicast”. A: Test that the module attribute is initialized. B: Test that the module attribute is a string. C: Test that the module attribute has a value of “multicast”.

    >>> _multicast.__module__ is not None
    True
    >>> type(_multicast.__module__) == type(str())
    True
    >>> type(_multicast.__module__)
    <class 'str'>
    >>> _multicast.__module__
    "multicast"
    >>>
multicast.__name__[source]

‘multicast’

The name of this program.

The __name__ attribute, like many dunder attributes, is associated with the implementation of Python language features. When utilizing this module as an imported module or a command-line interface (CLI) tool, the __name__ attribute can be safely disregarded. Within the context of this module, __name__ serves as a convenient constant that holds the human-readable name of the module.

Out of the three attributes: package, module, and name, it is recommended that name be used to programmatically obtain the value for formatting purposes, as it is specifically suited for that function.

Minimal Acceptance Testing:

First set up test fixtures by importing multicast.

    >>> import multicast as _multicast
    >>>

    >>> _multicast.__name__ is not None
    True
    >>>

Testcase 0: multicast.name should be the string “multicast”. A: Test that the name attribute is initialized. B: Test that the name attribute is a string. C: Test that the name attribute has a value of “multicast”.

    >>> _multicast.__name__ is not None
    True
    >>> type(_multicast.__name__) == type(str())
    True
    >>> type(_multicast.__name__)
    <class 'str'>
    >>> _multicast.__name__
    "multicast"
    >>>
multicast.__version__[source]

‘2.1.0-alpha-3’

The version of this program.

The __version__ attribute, like many dunder attributes, is associated with the implementation of Python language features. Within the context of this module, __version__ serves as a convenient constant that holds the version of the package.

Minimal Acceptance Testing:

First set up test fixtures by importing multicast.

    >>> import multicast as _multicast
    >>>

    >>> _multicast.__version__ is not None
    True
    >>>

Testcase 0: multicast.version should be the version string. A: Test that the version attribute is initialized. B: Test that the version attribute is a string. C: Test that the version attribute has a value with “.” dot(s).

    >>> _multicast.__version__ is not None
    True
    >>> type(_multicast.__version__) == type(str())
    True
    >>> type(_multicast.__version__)
    <class 'str'>
    >>> "." in _multicast.__version__
    True
    >>> "x" in _multicast.__version__
    False
    >>>
multicast.__prologue__[source]

None

The one-line description or summary of this program.

multicast.__doc__[source]

None

multicast._MCAST_DEFAULT_BUFFER_SIZE[source]

1316

Arbitrary buffer size to use by default, though any value below 65507 should work.

[!CAUTION] This value is NOT related to the actual packet size, the python socket module, and underlying OS, firmware and even some hardware will handle all of that. If you need to change buffers you are better off focusing on changing the underlying MTU of the entire network infrastructure instead (albeit that may not be possible for most users).

The value of this buffer is related to how this module ‘packetizes’ streams when encoding to, and decoding from, socket bytes and Python’s UTF-8 interpretation. There is no impact on how a python implementation will actually buffer network data in regards to the value of _MCAST_DEFAULT_BUFFER_SIZE at runtime.

Minimal Testing:

First set up test fixtures by importing multicast.

    >>> import multicast
    >>>

Testcase 0: Multicast should have a default buffer size. A: Test that the _MCAST_DEFAULT_BUFFER_SIZE attribute is initialized. B: Test that the _MCAST_DEFAULT_BUFFER_SIZE attribute is an int.

    >>> multicast._MCAST_DEFAULT_BUFFER_SIZE is not None
    True
    >>> type(multicast._MCAST_DEFAULT_BUFFER_SIZE) is type(1)
    True
    >>>
    >>> multicast._MCAST_DEFAULT_BUFFER_SIZE > int(1)
    True
    >>>

Testcase 1: Multicast should validate buffer size constraints. A: Test that the _MCAST_DEFAULT_BUFFER_SIZE attribute is initialized. B: Test that the _MCAST_DEFAULT_BUFFER_SIZE attribute is an int. C: Test that the _MCAST_DEFAULT_BUFFER_SIZE attribute is RFC-791 & RFC-768 compliant. D: Test that the _MCAST_DEFAULT_BUFFER_SIZE attribute is a smaller than fragment thresholds for typical ethernet MTUs by default.

    >>> multicast._MCAST_DEFAULT_BUFFER_SIZE is not None
    True
    >>> type(multicast._MCAST_DEFAULT_BUFFER_SIZE) is type(1)
    True
    >>>
    >>> multicast._MCAST_DEFAULT_BUFFER_SIZE >= int(56)
    True
    >>>
    >>> multicast._MCAST_DEFAULT_BUFFER_SIZE <= int(65527)
    True
    >>>
    >>> multicast._MCAST_DEFAULT_BUFFER_SIZE <= int(1500)
    True
    >>>
multicast._MCAST_DEFAULT_PORT[source]

59259

Arbitrary port to use by default, though any dynamic and free port would work.

A Value of “59259” is chosen as a default multicast port as per RFC-6335 on the rational that this memorable port will be treated as a user-allocated (caveat: senders should match the intended listener’s port)

[!IMPORTANT] Multicast is not actually port-aware, and port filtering is instead handled at the protocol layer (e.g., UDP) instead, and may not behave as expected for some real-world setups.

Minimal Testing:

First set up test fixtures by importing multicast.

    >>> import multicast
    >>>

Testcase 0: Multicast should have a default port. A: Test that the _MCAST_DEFAULT_PORT attribute is initialized. B: Test that the _MCAST_DEFAULT_PORT attribute is an int.

    >>> multicast._MCAST_DEFAULT_PORT is not None
    True
    >>> type(multicast._MCAST_DEFAULT_PORT) is type(1)
    True
    >>>
    >>> multicast._MCAST_DEFAULT_PORT > int(1024)
    True
    >>>

Testcase 1: Multicast should have a default port. A: Test that the _MCAST_DEFAULT_PORT attribute is initialized. B: Test that the _MCAST_DEFAULT_PORT attribute is an int. C: Test that the _MCAST_DEFAULT_PORT attribute is RFC-6335 compliant.

    >>> multicast._MCAST_DEFAULT_PORT is not None
    True
    >>> type(multicast._MCAST_DEFAULT_PORT) is type(1)
    True
    >>>
    >>> multicast._MCAST_DEFAULT_PORT >= int(49152)
    True
    >>>
    >>> multicast._MCAST_DEFAULT_PORT <= int(65535)
    True
    >>>
multicast._MCAST_DEFAULT_GROUP[source]

‘224.0.0.1’

Arbitrary group to use by default, though any mcst grp would work.

A Value of “224.0.0.1” is chosen as a default multicast group as per RFC-5771 on the rational that this group address will be treated as a local-net multicast (caveat: one should use link-local for ipv6)

Minimal Testing:

First set up test fixtures by importing multicast.

    >>> import multicast
    >>>

Testcase 0: Multicast should have a default port. A: Test that the _MCAST_DEFAULT_GROUP attribute is initialized. B: Test that the _MCAST_DEFAULT_GROUP attribute is an IP string.

    >>> multicast._MCAST_DEFAULT_GROUP is not None
    True
    >>> type(multicast._MCAST_DEFAULT_GROUP) is type(str)
    True
    >>>
multicast._MCAST_DEFAULT_TTL[source]

‘int(…)’

Arbitrary TTL time to live to use by default, though any small (1-126) TTL would work.

A Value of 1 (one TTL) is chosen as per RFC1112 Sec 6.1 on the rational that an explicit value that could traverse byond the local connected network should be chosen by the caller rather than the default value. This is inline with the principle of none, one or many.

Minimal Testing:

First set up test fixtures by importing multicast.

    >>> import multicast
    >>>

Testcase 0: Multicast should have a default TTL. A: Test that the _MCAST_DEFAULT_TTL attribute is initialized. B: Test that the _MCAST_DEFAULT_TTL attribute is an int. c: Test that the _MCAST_DEFAULT_TTL attribute is default of 1.

    >>> multicast._MCAST_DEFAULT_TTL is not None
    True
    >>> type(multicast._MCAST_DEFAULT_TTL) is type(1)
    True
    >>> (int(multicast._MCAST_DEFAULT_TTL) >= int(0))
    True
    >>> (int(multicast._MCAST_DEFAULT_TTL) <= int(2))
    True
    >>>
multicast._BLANK[source]

‘str(…)’

Arbitrary blank string.

Minimal Testing:

First set up test fixtures by importing multicast.

    >>> import multicast
    >>> _BLANK = multicast._BLANK

Testcase 0: Multicast should have a default port. A: Test that the _BLANK attribute is initialized. B: Test that the _BLANK attribute is an empty string.

    >>> _BLANK is not None
    True
    >>> type(_BLANK) is type(str)
    True
    >>>
    >>> len(_BLANK) <= 0
    True
    >>>
multicast.EXIT_CODES[source]

None

See multicast.exceptions.EXIT_CODES.

multicast.EXCEPTION_EXIT_CODES[source]

None

See multicast.exceptions.EXCEPTION_EXIT_CODES.

multicast.CommandExecutionError[source][source]

None

See multicast.exceptions.CommandExecutionError Class.

multicast.ShutdownCommandReceived[source][source]

None

See multicast.exceptions.ShutdownCommandReceived Class.

multicast.get_exit_code_from_exception[source][source]

None

See multicast.exceptions.get_exit_code_from_exception function.

multicast.exit_on_exception[source][source]

None

See multicast.exceptions.exit_on_exception function.

class multicast.mtool[source][source]

Bases: abc.ABC

Class for Multicast tools.

Utility class for CLI tools of the Multicast package. setupArgs() and doStep() are abstract and need to be implemented by subclasses.

Minimal Acceptance Testing:

    First set up test fixtures by importing multicast.

    >>> import multicast as _multicast
    >>> _multicast.mtool is not None
    True
    >>>

Testcase 0: multicast.mtool should be the abstract class “multicast.mtool”. A: Test that the mtool abstract class is partially implemented. B: Test that the mtool abstract class has abstract methods.

    >>> _multicast.mtool is not None
    True
    >>> type(_multicast.mtool) #doctest: +ELLIPSIS
    <...abc.ABC...>
    >>> hasattr(_multicast.mtool, "__abstractmethods__")
    True
    >>>

Testcase 1: multicast.mtool should have two key abstract methods. A: Test that the mtool abstract class has at-least two (2) abstract methods. B: Test that the mtool abstract class has the abstract method “dostep”. C: Test that the mtool abstract class has the abstract method “setupArgs”.

    >>> hasattr(_multicast.mtool, "__abstractmethods__")
    True
    >>> len(_multicast.mtool.__abstractmethods__) >= int(2)
    True
    >>> "doStep" in _multicast.mtool.__abstractmethods__
    True
    >>> "setupArgs" in _multicast.mtool.__abstractmethods__
    True
    >>>

Testcase 2: multicast.mtool should allow sub-classes to be callable. A: Test that the mtool abstract class can be sub-classes. B: Test that the mtool abstract class has the implemented method “buildArgs”. B: Test that the mtool abstract class has the implemented method “parseArgs”.

    >>> hasattr(_multicast.mtool, "__abstractmethods__")
    True
    >>> len(_multicast.mtool.__abstractmethods__) >= int(2)
    True
    >>> "doStep" in _multicast.mtool.__abstractmethods__
    True
    >>> "setupArgs" in _multicast.mtool.__abstractmethods__
    True
    >>> _test_dir_fixture = dir(_multicast.mtool)
    >>> _test_dir_fixture is not None
    True
    >>> "buildArgs" in _test_dir_fixture
    True
    >>> "parseArgs" in _test_dir_fixture
    True
    >>> class test_class_fixture(_multicast.mtool):
    ...     def doStep(self, *args):
    ...             return (True, 42)
    ...
    ...     @classmethod
    ...     def setupArgs(cls, parser):
    ...             parser.add_parser("NOOP", help="Does Nothing.")
    ...             return parser
    ...
    >>>
    >>> tst_fxtr_args = ['''NOOP''']
    >>> test_fixture = test_class_fixture.parseArgs(tst_fxtr_args)
    >>> test_fixture is not None
    True
    >>> test_fixture_inst = test_class_fixture()
    >>> test_fixture_inst is not None
    True
    >>> test_fixture_inst(False) #doctest: +ELLIPSIS
    (...42...)
    >>> del test_fixture_inst
    >>>
__module__[source]

‘multicast’

__proc__[source]

None

__prologue__[source]

‘Add a prologue here.’

__epilogue__[source]

‘Add an epilogue here.’

classmethod buildArgs(calling_parser_group: argparse.ArgumentParser) argparse.ArgumentParser[source][source]

Will build the argparse parser.

Utility Function to build the argparse parser; see argparse.ArgumentParser for more. returns argparse.ArgumentParser - the ArgumentParser to use.

Minimal Acceptance Testing:

First set up test fixtures by importing multicast.

    >>> import multicast
    >>> multicast.mtool is not None
    True
    >>>

Testcase 0: buildArgs should return an ArgumentParser. A: Test that the multicast.mtool component is initialized. B: Test that the mtool.buildArgs component is initialized.

    >>> multicast.mtool is not None
    True
    >>> type(multicast.mtool) #doctest: +ELLIPSIS
    <...abc.ABCMeta...>
    >>> multicast.mtool.buildArgs is not None
    True
    >>> class test_tool_fixture(multicast.mtool):
    ...     def doStep(self, *args):
    ...             pass
    ...
    ...     @classmethod
    ...     def setupArgs(cls, parser):
    ...             return parser
    ...
    >>>
    >>> type(test_tool_fixture.buildArgs(None)) #doctest: -DONT_ACCEPT_BLANKLINE, +ELLIPSIS
    <...ArgumentParser...>
    >>>
    >>>
classmethod parseArgs(arguments) tuple[source][source]

Will attempt to parse the given CLI arguments.

See argparse.ArgumentParser for more. param str - arguments - the array of arguments to parse. Usually sys.argv[1:] returns argparse.Namespace - the Namespace parsed with the key-value pairs.

Minimal Acceptance Testing:

First set up test fixtures by importing multicast.

    >>> import multicast
    >>> multicast.mtool is not None
    True
    >>>

Testcase 0: parseArgs should return a namespace. A: Test that the multicast.mtool component is initialized. B: Test that the multicast.mtool.parseArgs component is initialized.

    >>> multicast.mtool is not None
    True
    >>> multicast.mtool.parseArgs is not None
    True
    >>> class test_tool_fixture(multicast.mtool):
    ...     def doStep(self, *args):
    ...             pass
    ...
    ...     @classmethod
    ...     def setupArgs(cls, parser):
    ...             parser.add_parser("NOOP", help="Does Nothing.")
    ...             return parser
    ...
    >>>
    >>> tst_fxtr_args = ['''NOOP''', '''--port=1234''', '''--iface=127.0.0.1''']
    >>> test_fixture = test_tool_fixture.parseArgs(tst_fxtr_args)
    >>> test_fixture is not None
    True
    >>> type(test_fixture) #doctest: -DONT_ACCEPT_BLANKLINE, +ELLIPSIS
    <...tuple...>
    >>> tst_fxtr_args_2 = ['''NOOP''', '''--junk''', '''--more-trash=stuff''']
    >>> (test_fixture_2, test_ignore_extras) = test_tool_fixture.parseArgs(tst_fxtr_args_2)
    >>> test_fixture_2 is not None
    True
    >>> type(test_fixture_2) #doctest: -DONT_ACCEPT_BLANKLINE, +ELLIPSIS
    <...Namespace...>
    >>>
classmethod checkToolArgs(args) list[source][source]

Will handle the None case for arguments.

Used as a helper function.

Minimal Acceptance Testing:

First set up test fixtures by importing multicast.

    >>> import multicast
    >>>

Testcase 0: multicast.mtool should have a doctests.

    >>> import multicast
    >>> multicast.mtool is not None
    True
    >>> multicast.mtool.__class__ is not None
    True
    >>>
    >>> multicast.mtool.__doc__ is not None
    True
    >>>

Testcase 1: multicast.checkToolArgs should return an array.

    >>> import multicast
    >>> multicast.mtool.checkToolArgs(None) is not None
    True
    >>> type(multicast.mtool.checkToolArgs(None)) is type([None])
    True
    >>>

Testcase 2: multicast.checkToolArgs should return an array.

    >>> import multicast
    >>> type(multicast.mtool.checkToolArgs(["arg1", "arg2"])) is type(["strings"])
    True
    >>> type(multicast.mtool.checkToolArgs([0, 42])) is type([int(1)])
    True
    >>>
__call__(*args, **kwargs)[source][source]

Call self as a function.

    Default implementation simply calls the abstract function doStep
    and passes the given positional arguments, thus key-word arguments
    will be silently ignored.

    Subclasses should not reimplement __call__ directly and instead
    should implement necessary logic in the abstract doStep() function.
abstractmethod classmethod setupArgs(parser) None[source][source]

Abstract hook for setting up the tool’s arguments.

abstractmethod doStep(*args, **kwargs) tuple[source][source]

Abstracts the call behavior for sub-classing the tool.

This method should be overridden by subclasses to implement the specific functionality of each multicast tool. It accepts variable positional and keyword arguments as needed by the specific implementation.

Args: *args: Variable length argument list. **kwargs: Arbitrary keyword arguments.

Returns: tuple: A tuple containing a status indicator and a result message.

Raises: NotImplementedError: If the subclass does not implement this method.

multicast.genSocket[source][source]

None

See multicast.skt.genSocket.

multicast.endSocket[source][source]

None

See multicast.skt.endSocket.