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.3.tar.gz (26.9 kB view details)

Uploaded Source

Built Distribution

easyprotocol-0.0.3-py3-none-any.whl (44.9 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: easyprotocol-0.0.3.tar.gz
  • Upload date:
  • Size: 26.9 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.3.tar.gz
Algorithm Hash digest
SHA256 c7444c1a659b7855b37d0014a5a7baa6b2b623975d58d1bdebbca889b352f809
MD5 4e9be950fb006045f484c3fd10d5a23c
BLAKE2b-256 c09bc76a2e00b2ce5e227864a7be18714598973dac4b5a4ff7072248fad56af4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for easyprotocol-0.0.3-py3-none-any.whl
Algorithm Hash digest
SHA256 068486d21ab8f0cbdfc0902c1cd5f53c2544adbe74c82cd75f15df502afeaa7c
MD5 f2370a5dd4081a5e3a92a2d554c490b6
BLAKE2b-256 4a5085150b2a57fe1168a9fe36d373b3ae8e110128921e2ceaa1a2ccea224e08

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