Skip to main content

Schematics extension for handling protobuf 3 messages.

Project description

schematics-proto3

Built upon Schematics - Python Data Structures for Humans™, schematics-proto3 brings the awesome features of Schematics to Protobuf 3 world.

Build codecov Documentation Status PyPI version

Caution

Library is currently in WORK IN PROGRESS state.

What is implemented and tested:

  1. Loading Protobuf 3 messages to Model instances.
    • for most of the Protobuf 3 types, including wrappers, repeated oneof fields
    • Enum type
  2. Validation and structured error messages.

To be done:

  1. Serializing Model instances to Protobuf 3 messages.
  2. Make the library more user-friendly.
  3. Schematics "roles".

Installation

pip install schematics-proto3

Motivation

As good and widely supported as it is, Protobuf 3 still has some quirks which can make working with it painful and repetitive. Especially, building complex gRPC services might reveal a number of deficiencies in available tooling.

schematics-proto3 aims to address this problem, in particular:

  • [#359] default values and testing if a field is set in v3

    There is a workaround for this, schematics-proto3 incorporates wrapper types to hide nested messages underneath.

  • no proper data handling library

    Comparing to Serializers in Django Rest Framework or Marshmallow, there seems to be no full fledged serialization / validation / deserialization library for Protobuf 3. Thanks to Schematics, schematics-proto3 is able to provide:

    • declarative models
    • custom validation functions
    • structured error messages (currently only as Python dict)

Example

Let's take Schematics example and modify it to work with Protobuf.

We have a following Protobuf message (and person_pb2 Python module).

syntax = "proto3";

import "google/protobuf/wrappers.proto";

package example;

message Person {
  google.protobuf.StringValue name = 1;
  google.protobuf.StringValue website = 2;
}

And reflect above message in Model class.

from schematics_proto3 import Model
from schematics_proto3 import types as pbtypes

import person_pb2 as pb2


class PersonModel(Model, protobuf_message=pb2.Person):
    name = pbtypes.StringWrapperType()
    website = pbtypes.StringWrapperType()

Let's load some data.

msg = pb2.Person()
msg.name.value = 'Jon Doe'
msg.website.value = 'https://example.com'

model = PersonModel.load_protobuf(msg)
model.validate()

assert model.name == 'Jon Doe'
assert model.website == 'https://example.com'

assert model.to_native() == {'name': 'Jon Doe', 'website': 'https://example.com'}

Not setting a field will give you an Unset.

from schematics_proto3.unset import Unset

msg = pb2.Person()
msg.name.value = 'Jon Doe'

model = PersonModel.load_protobuf(msg)
model.validate()

assert model.name == 'Jon Doe'
assert model.website is Unset

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

schematics-proto3-0.1.3.tar.gz (46.9 kB view hashes)

Uploaded Source

Built Distribution

schematics_proto3-0.1.3-py3-none-any.whl (15.6 kB view hashes)

Uploaded Python 3

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