Skip to main content

A library for quick protocol prototyping and parsing.

Project description

EasyProtocol

Introduction

A library for quick prototyping protocol parsing in python. Not the fastest, not the most efficient, not the coolest, but hopefully the easiest to modify and prototype with.

Quick Start

Installing

For now you have to install from source, this will be on pypi soon.

  • Current Method
git clone https://github.com/joeferg425/EasyProtocol.git .
cd EasyProtocol
python -m pip install .
  • Future, better method
python -m pip install easyprotocol

Example 1 - Making a Parser From a List of Fields

  • Demo Code

    Lets parse something like the following.

    Name Bit Count Data Type
    id 8 8-bit int
    data count 16 16-bit unsigned int
    data 8 8-bit unsigned int

    Fixed frame definition. Nothing fancy.

    """Define your parser using simple python classes and familiar types."""
    from easyprotocol.base import ParseFieldList, hex
    from easyprotocol.fields import Int8Field, UInt8Field, UInt16Field
    
    # Make an instance of the modified list type and add your fields as the list items.
    exampleParser = ParseFieldList(
        # give the parser a name
        name="ExampleParser1",
        # define your fields in order
        default=[
            # give each field a name, some standard field types are already defined.
            Int8Field(name="id"),
            UInt16Field(name="count"),
            UInt8Field(name="data"),
        ],
    )
    
    # Some example data bytes to parse
    data = b"\x01\x00\x01\x80"
    print(f"input bytes:\t{data!r}")
    print(f"input hex:\t{hex(data)}\n")
    
    # Parse the bytes
    exampleParser.parse(data=data)
    
    # Print the parsed data to see what we got
    print(f"parsed:\t{exampleParser}")
    print(f"bytes:\t{bytes(exampleParser)!r}")
    print(f"hex:\t{exampleParser.hex_value}\n")
    
    # Make a new frame from known data to send somewhere (like a socket)
    exampleParser[0].value = 3
    exampleParser.value = [3, 257, 127]
    exampleParser.value = [3, 257, 127]
    print(f"parsed:\t{exampleParser}")
    print(f"bytes:\t{bytes(exampleParser)!r}")
    print(f"hex:\t{exampleParser.hex_value}\n")
    
    # You can access parsed elements of a ParseList by numeric index.
    for child in exampleParser.children.values():
        print(f'{child.name}:\t{child.value}\t"{child.string_value}"')
    print()
    
    # Wait, I don't really like hexadecimal
    exampleParser.string_format = "{}"
    for child in exampleParser.children.values():
        child.string_format = "{}"
    
    # Print the values again
    exampleParser[0].value = 3
    exampleParser.value = [3, 257, 127]
    exampleParser.value = [3, 257, 127]
    print(f"parsed:\t{exampleParser}")
    print(f"bytes:\t{bytes(exampleParser)!r}")
    print(f"hex:\t{exampleParser.hex_value}\n")
    for child in exampleParser.children.values():
        print(f'{child.name}:\t{child.value}\t"{child.string_value}"')
    
  • Output

    input bytes:    b'\x01\x00\x01\x80'
    input hex:      01 00 01 80
    
    parsed: ExampleParser1: [id: 1, count: 0001(hex), data: 80(hex)]
    bytes:  b'\x01\x00\x01\x80'
    hex:    01 00 01 80
    
    parsed: ExampleParser1: [id: 3, count: 0101(hex), data: 7F(hex)]
    bytes:  b'\x03\x01\x01\x7f'
    hex:    03 01 01 7F
    
    id:     3       "3"
    count:  257     "0101(hex)"
    data:   127     "7F(hex)"
    
    parsed: ExampleParser1: [id: 3, count: 257, data: 127]
    bytes:  b'\x03\x01\x01\x7f'
    hex:    03 01 01 7F
    
    id:     3       "3"
    count:  257     "257"
    data:   127     "127"
        ```
    

Example 2 - Making a Parser from a Dictionary of Fields

  • Demo Code

    Lets parse something like the following.

    Name Bit Count Data Type
    id 8 8-bit unsigned int
    count 16 16-bit unsigned int
    data array 8 8-bit unsigned int(s)

    Variable Frame size, handles a variable length array of uint8 chunks.

    """Define your parser using simple python classes and familiar types."""
    from typing import cast
    
    from easyprotocol.base import ParseFieldDict, ParseFieldList, hex
    from easyprotocol.fields import Int8Field, ParseArrayField, UInt8Field, UInt16Field
    
    # you can define your field classes before using them in a parser.
    ident = Int8Field(name="id")
    count = UInt16Field(
        name="count",
        # Let's modify the display of the field value
        string_format="{} data items",
    )
    data_array = ParseArrayField(
        name="data",
        count=count,
        array_item_class=UInt8Field,
        array_item_default=0,
    )
    
    # Make an instance of the modified list type and add your fields as the list items.
    exampleParser = ParseFieldDict(
        # give the parser a name
        name="ExampleParser",
        # define your fields in order
        default=[
            # give each field a name, some standard types are defined for you.
            ident,
            count,
            data_array,
        ],
    )
    
    # Some example data bytes to parse
    data = b"\x01\x00\x01\x80"
    print(f"input bytes:\t{data!r}\n")
    print(f"input hex:\t{hex(data)}\n")
    
    # Parse the bytes
    exampleParser.parse(data=data)
    # Print the parsed data to see what we got
    print(f"parsed:\t{exampleParser}")
    print(f"hex:\t{hex(exampleParser)}\n")
    
    # Make a new frame from known data to send somewhere (like a socket)
    exampleParser["id"].value = 3
    exampleParser["count"].value = 2
    exampleParser["data"].value = [
        127,
        UInt8Field(name="new data", default=15),
    ]
    
    print(f"parsed:\t{exampleParser}")
    print(f"hex:\t{hex(exampleParser)}\n")
    
    # You can access parsed elements of a ParseDict by name.
    idField = exampleParser[ident.name]
    dataCountField = exampleParser[count.name]
    dataField = cast(ParseFieldList, exampleParser[data_array.name])
    
    # The ArrayField is a list type, so children are accessed by numeric index.
    for child in exampleParser.values():
        print(f"{child.name}:\t{child.value}\t\t{child.bits_str}")
    
  • Output

    input bytes:    b'\x01\x00\x01\x80'
    
    input hex:      01 00 01 80
    
    parsed: ExampleParser: {id: 1, count: 1 data items, data: [#0: 80(hex)]}
    hex:    01 00 01 80
    
    parsed: ExampleParser: {id: 3, count: 2 data items, data: [#0: 7F(hex), #1: 0F(hex)]}
    hex:    03 00 02 7F 0F
    
    id:     3               00000011:<b
    count:  2               0000000000000010:<b
    data:   [<UInt8Field> #0: 7F(hex), <UInt8Field> #1: 0F(hex)]            0111111100001111:<b
        ```
    

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

easyprotocol-0.0.2.tar.gz (22.8 kB view details)

Uploaded Source

Built Distribution

easyprotocol-0.0.2-py3-none-any.whl (38.4 kB view details)

Uploaded Python 3

File details

Details for the file easyprotocol-0.0.2.tar.gz.

File metadata

  • Download URL: easyprotocol-0.0.2.tar.gz
  • Upload date:
  • Size: 22.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.9.5

File hashes

Hashes for easyprotocol-0.0.2.tar.gz
Algorithm Hash digest
SHA256 90d21bf68363f5137d7638e59d5c156723067bc23a340c64e452aec776b30e39
MD5 5bd5d3e15775c99f0842d3620daa75c8
BLAKE2b-256 e9080886da5147ea8dc11508a2104ca3c4b4e8103b72db45f8061a5aad9d5a1c

See more details on using hashes here.

File details

Details for the file easyprotocol-0.0.2-py3-none-any.whl.

File metadata

File hashes

Hashes for easyprotocol-0.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 e314238dbd3f09b7301b143d7533e8fed220645f846a9d7d54509e54582d2478
MD5 e31ddec9d8d305c7f28e38efc7deb3be
BLAKE2b-256 9662ce2ab5f2cc3bc40683397c13c1f408fbb1c703810c8030405eb39c7946ab

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page