Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/kszucs/proxo
Extensible protobuf messages with python methods properties
https://github.com/kszucs/proxo
dictionary magic protobuf python
Last synced: about 1 month ago
JSON representation
Extensible protobuf messages with python methods properties
- Host: GitHub
- URL: https://github.com/kszucs/proxo
- Owner: kszucs
- License: apache-2.0
- Created: 2016-11-06T17:07:48.000Z (about 8 years ago)
- Default Branch: master
- Last Pushed: 2016-11-08T07:37:52.000Z (about 8 years ago)
- Last Synced: 2024-05-02T01:56:51.809Z (7 months ago)
- Topics: dictionary, magic, protobuf, python
- Language: Protocol Buffer
- Size: 104 KB
- Stars: 2
- Watchers: 4
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.rst
- License: LICENSE
Awesome Lists containing this project
README
|Build Status|
Proxo
=====Extend protobuf message with custom methods properties and additional
attributesTL;DR
-----.. code:: python
from proxo import MessageProxy, encode, decode
class Person(MessageProxy):
proto = addressbook_pb2.Person # it can be more complex, like pattern matching, see below@property
def firstname(self):
return self.name.split(' ')[0]p = Person(name='Test Me')
assert p.firstname == 'Test'
assert decode(encode(p)) == pUsage
-----Given the addressbook protobuf definition
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~.. code:: protobuf
package tutorial;
message Person {
required string name = 1;
required int32 id = 2;
optional string email = 3;enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}message PhoneNumber {
required string number = 1;
optional PhoneType type = 2 [default = HOME];
}repeated PhoneNumber phone = 4;
}message AddressBook {
repeated Person person = 1;
}The traditional way
~~~~~~~~~~~~~~~~~~~.. code:: python
import addressbook_pb2
person = addressbook_pb2.Person()
person.id = 1234
person.name = "John Doe"
person.email = "[email protected]"
phone = person.phone.add()
phone.number = "555-4321"
phone.type = addressbook_pb2.Person.HOMEvia Proxo.dict\_to\_protobuf
~~~~~~~~~~~~~~~~~~~~~~~~~~~~.. code:: python
from proxo import dict_to_protobuf, protobuf_to_dict
data = {'id': 124,
'name': 'John Doe',
'email': '[email protected]',
'phone': {'number': '555-4321',
'type': 'HOME'}}proto = dict_to_protobuf(data, addressbook_pb2.Person)
assert person == proto
# converting back
mapping = protobuf_to_dict(proto)
mapping['phone']['number']
mapping.phone.number # using dot notationassert mapping == data
via extending Proxo.MessageProxy
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~.. code:: python
from proxo import MessageProxy, encode, decode
# note that non defined types will be automatically proxied too
class Person(MessageProxy):
proto = addressbook_pb2.Person # it can be more complex, like pattern matching, see below@property
def firstname(self):
return self.name.split(' ')[0]def call(self):
try:
print('calling {}'.format(self.firstname))
do_voip_call(self.phone.number)
except:
print('failed calling {} on his/her {} number'.format(self.firstname,
self.phone.type.lower))obj = Person(id=124, name='John Doe', phone={'number': '555-4321',
'type': 'HOME'})
obj.phone.type = 'MOBILE'
assert obj.firsname == 'John'proto = encode(obj)
john = decode(proto)# lets bother him
john.call()More Complicated Example
------------------------.. code:: python
import operator
from uuid import uuid4
from functools import partial
from proxo import MessageProxyclass Scalar(MessageProxy):
proto = mesos_pb2.Value.Scalarclass Resource(MessageProxy):
proto = mesos_pb2.Resource # can be classclass ScalarResource(Resource):
proto = mesos_pb2.Resource(type=mesos_pb2.Value.SCALAR) # or partially set instancedef __init__(self, value=None, **kwargs):
super(Resource, self).__init__(**kwargs)
if value is not None:
self.scalar = Scalar(value=value)def __cmp__(self, other):
first, second = float(self), float(other)
if first < second:
return -1
elif first > second:
return 1
else:
return 0def __repr__(self):
return "<{}: {}>".format(self.__class__.__name__, self.scalar.value)def __float__(self):
return float(self.scalar.value)@classmethod
def _op(cls, op, first, second):
value = op(float(first), float(second))
return cls(value=value)def __add__(self, other):
return self._op(operator.add, self, other)def __radd__(self, other):
return self._op(operator.add, other, self)def __sub__(self, other):
return self._op(operator.sub, self, other)def __rsub__(self, other):
return self._op(operator.sub, other, self)def __mul__(self, other):
return self._op(operator.mul, self, other)def __rmul__(self, other):
return self._op(operator.mul, other, self)def __truediv__(self, other):
return self._op(operator.truediv, self, other)def __rtruediv__(self, other):
return self._op(operator.truediv, other, self)def __iadd__(self, other):
self.scalar.value = float(self._op(operator.add, self, other))
return selfdef __isub__(self, other):
self.scalar.value = float(self._op(operator.sub, self, other))
return selfclass Cpus(ScalarResource):
proto = mesos_pb2.Resource(name='cpus', type=mesos_pb2.Value.SCALAR)class Mem(ScalarResource):
proto = mesos_pb2.Resource(name='mem', type=mesos_pb2.Value.SCALAR)class Disk(ScalarResource):
proto = mesos_pb2.Resource(name='disk', type=mesos_pb2.Value.SCALAR).. |Build Status| image:: http://drone.lensa.com:8000/api/badges/kszucs/proxo/status.svg
:target: http://drone.lensa.com:8000/kszucs/proxo