Skip to main content

Decode protobuf binary data to JSON without schema definition

Project description

proto2json

PyPI version Python versions License: MIT

Decode protobuf binary data to JSON without requiring a schema definition (.proto file).

Features

  • 🚀 No Schema Required: Decode protobuf data without .proto files
  • 🔍 Type Detection: Automatically detects strings, nested messages, and numeric types
  • 📊 Multiple Interpretations: Provides multiple type interpretations for ambiguous fields
  • 🎯 Simple API: Easy-to-use interface with just two main functions
  • 📦 Zero Dependencies: No external dependencies required

Installation

pip install proto2json

Quick Start

from proto2json import decode_protobuf, decode_protobuf_to_json

# Decode protobuf bytes to Python dict
protobuf_bytes = b'\x08\x96\x01\x12\x07\x74\x65\x73\x74\x69\x6e\x67'
result = decode_protobuf(protobuf_bytes)
print(result)

# Decode to JSON string
json_str = decode_protobuf_to_json(protobuf_bytes)
print(json_str)

Output Format

The decoder returns a dictionary where keys are field numbers (as strings) and values contain:

Wire Type 0 (Varint)

{
    "wire_type": 0,
    "value": 150,
    "as_signed": -150  # Only present if value could be negative
}

Wire Type 1 (Fixed64)

{
    "wire_type": 1,
    "as_fixed64": 123456789,
    "as_sfixed64": -123456789,
    "as_double": 1.23456789
}

Wire Type 2 (Length-Delimited)

String:

{
    "wire_type": 2,
    "type": "string",
    "value": "hello world"
}

Nested Message:

{
    "wire_type": 2,
    "type": "message",
    "value": {
        "1": {"wire_type": 0, "value": 42}
    }
}

Bytes:

{
    "wire_type": 2,
    "type": "bytes",
    "value": "48656c6c6f"  # hex encoded
}

Wire Type 5 (Fixed32)

{
    "wire_type": 5,
    "as_fixed32": 12345,
    "as_sfixed32": -12345,
    "as_float": 123.45
}

API Reference

decode_protobuf(data: bytes) -> Dict[str, Any]

Decode protobuf binary data into a JSON-compatible dictionary.

Parameters:

  • data (bytes): Protobuf serialized bytes

Returns:

  • Dict with field numbers as string keys and decoded values

Example:

data = b'\x08\x96\x01'  # field 1, varint 150
result = decode_protobuf(data)
# {'1': {'wire_type': 0, 'value': 150}}

decode_protobuf_to_json(data: bytes, indent: int = 2) -> str

Decode protobuf binary data and return as JSON string.

Parameters:

  • data (bytes): Protobuf serialized bytes
  • indent (int, optional): JSON indentation level. Use None for compact output. Default: 2

Returns:

  • JSON string representation of the decoded protobuf

Example:

json_str = decode_protobuf_to_json(data, indent=2)
print(json_str)

Wire Type Constants

The package exports wire type constants for reference:

from proto2json import (
    WIRE_TYPE_VARINT,           # 0
    WIRE_TYPE_FIXED64,          # 1
    WIRE_TYPE_LENGTH_DELIMITED, # 2
    WIRE_TYPE_FIXED32,          # 5
)

Advanced Usage

Handling Repeated Fields

Repeated fields are automatically detected and merged into arrays:

# Protobuf with repeated field
data = b'\x08\x01\x08\x02\x08\x03'  # field 1 appears 3 times
result = decode_protobuf(data)
# {
#   '1': [
#     {'wire_type': 0, 'value': 1},
#     {'wire_type': 0, 'value': 2},
#     {'wire_type': 0, 'value': 3}
#   ]
# }

Nested Messages

Nested messages are recursively decoded:

# Protobuf with nested message
result = decode_protobuf(data)
# {
#   '1': {
#     'wire_type': 2,
#     'type': 'message',
#     'value': {
#       '1': {'wire_type': 0, 'value': 42}
#     }
#   }
# }

How It Works

The decoder uses the protobuf wire format specification to parse the binary data:

  1. Field Detection: Reads field numbers and wire types
  2. Type Inference:
    • For length-delimited fields, tries to detect if it's a message, string, or raw bytes
    • For fixed-width fields, provides multiple numeric interpretations
  3. Recursive Decoding: Nested messages are automatically detected and decoded

Limitations

  • Type Ambiguity: Without a schema, some types are ambiguous (e.g., a varint could be int32, int64, bool, or enum)
  • Packed Fields: Packed repeated fields are decoded as raw bytes
  • Groups: Deprecated protobuf groups are not supported
  • Enums: Enum values are decoded as integers

Use Cases

  • Debugging: Inspect protobuf messages without access to .proto files
  • Reverse Engineering: Analyze unknown protobuf data structures
  • Data Recovery: Recover data from protobuf files when schemas are lost
  • Testing: Quick protobuf data inspection during development

Examples

See the examples directory for more usage examples.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Acknowledgments

Inspired by protobuf_inspector project.

Changelog

v1.0.0 (2026-01-09)

  • Initial release
  • Support for all standard protobuf wire types
  • Automatic type detection for length-delimited fields
  • Recursive nested message decoding

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

proto2json-1.0.0.tar.gz (8.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

proto2json-1.0.0-py3-none-any.whl (8.1 kB view details)

Uploaded Python 3

File details

Details for the file proto2json-1.0.0.tar.gz.

File metadata

  • Download URL: proto2json-1.0.0.tar.gz
  • Upload date:
  • Size: 8.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.8.3

File hashes

Hashes for proto2json-1.0.0.tar.gz
Algorithm Hash digest
SHA256 7e020bc8df346731b8f5e8dd8ec93a8cfdf34d38506d3e41bc2f22408167a399
MD5 f253d2ee4baf2aea14acb3ba3daf7fb4
BLAKE2b-256 5f5b7a384a8e0d1c437a1fd72ead814f945023c7b1a2c1f82b03246958a6ae4e

See more details on using hashes here.

File details

Details for the file proto2json-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: proto2json-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 8.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.8.3

File hashes

Hashes for proto2json-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 28705491a7e13e06a55996754780ed36a91b7b8b371c8a4a9658d3f82840ca19
MD5 e06e139cf431b6364f99b29743e297c1
BLAKE2b-256 04c7c7e1dce3f44d1cb73d7d0aa13d383250ae872ffbddf62fe9ee3ba2309cd4

See more details on using hashes here.

Supported by

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