Add Documentation (#125)
Add sphinx docs with readthedocs integration. Docs can be built locally with `poe docs`.
This commit is contained in:
@@ -120,8 +120,8 @@ DATETIME_ZERO = datetime_default_gen()
|
||||
class Casing(enum.Enum):
|
||||
"""Casing constants for serialization."""
|
||||
|
||||
CAMEL = camel_case
|
||||
SNAKE = snake_case
|
||||
CAMEL = camel_case #: A camelCase sterilization function.
|
||||
SNAKE = snake_case #: A snake_case sterilization function.
|
||||
|
||||
|
||||
PLACEHOLDER: Any = object()
|
||||
@@ -249,11 +249,26 @@ def map_field(
|
||||
|
||||
|
||||
class Enum(enum.IntEnum):
|
||||
"""Protocol buffers enumeration base class. Acts like `enum.IntEnum`."""
|
||||
"""
|
||||
The base class for protobuf enumerations, all generated enumerations will inherit
|
||||
from this. Bases :class:`enum.IntEnum`.
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def from_string(cls, name: str) -> int:
|
||||
"""Return the value which corresponds to the string name."""
|
||||
def from_string(cls, name: str) -> "Enum":
|
||||
"""
|
||||
Return the value which corresponds to the string name.
|
||||
|
||||
Parameters
|
||||
-----------
|
||||
name: :class:`str`
|
||||
The name of the enum member to get
|
||||
|
||||
Raises
|
||||
-------
|
||||
:exc:`ValueError`
|
||||
The member was not found in the Enum.
|
||||
"""
|
||||
try:
|
||||
return cls._member_map_[name]
|
||||
except KeyError as e:
|
||||
@@ -497,9 +512,15 @@ class ProtoClassMetadata:
|
||||
|
||||
class Message(ABC):
|
||||
"""
|
||||
A protobuf message base class. Generated code will inherit from this and
|
||||
register the message fields which get used by the serializers and parsers
|
||||
to go between Python, binary and JSON protobuf message representations.
|
||||
The base class for protobuf messages, all generated messages will inherit from
|
||||
this. This class registers the message fields which are used by the serializers and
|
||||
parsers to go between the Python, binary and JSON representations of the message.
|
||||
|
||||
.. container:: operations
|
||||
|
||||
.. describe:: bytes(x)
|
||||
|
||||
Calls :meth:`__bytes__`.
|
||||
"""
|
||||
|
||||
_serialized_on_wire: bool
|
||||
@@ -605,7 +626,7 @@ class Message(ABC):
|
||||
|
||||
def __bytes__(self) -> bytes:
|
||||
"""
|
||||
Get the binary encoded Protobuf representation of this instance.
|
||||
Get the binary encoded Protobuf representation of this message instance.
|
||||
"""
|
||||
output = bytearray()
|
||||
for field_name, meta in self._betterproto.meta_by_field_name.items():
|
||||
@@ -684,7 +705,20 @@ class Message(ABC):
|
||||
return bytes(output)
|
||||
|
||||
# For compatibility with other libraries
|
||||
SerializeToString = __bytes__
|
||||
def SerializeToString(self: T) -> bytes:
|
||||
"""
|
||||
Get the binary encoded Protobuf representation of this message instance.
|
||||
|
||||
.. note::
|
||||
This is a method for compatibility with other libraries,
|
||||
you should really use ``bytes(x)``.
|
||||
|
||||
Returns
|
||||
--------
|
||||
:class:`bytes`
|
||||
The binary encoded Protobuf representation of this message instance
|
||||
"""
|
||||
return bytes(self)
|
||||
|
||||
@classmethod
|
||||
def _type_hint(cls, field_name: str) -> Type:
|
||||
@@ -788,6 +822,16 @@ class Message(ABC):
|
||||
"""
|
||||
Parse the binary encoded Protobuf into this message instance. This
|
||||
returns the instance itself and is therefore assignable and chainable.
|
||||
|
||||
Parameters
|
||||
-----------
|
||||
data: :class:`bytes`
|
||||
The data to parse the protobuf from.
|
||||
|
||||
Returns
|
||||
--------
|
||||
:class:`Message`
|
||||
The initialized message.
|
||||
"""
|
||||
# Got some data over the wire
|
||||
self._serialized_on_wire = True
|
||||
@@ -838,20 +882,47 @@ class Message(ABC):
|
||||
# For compatibility with other libraries.
|
||||
@classmethod
|
||||
def FromString(cls: Type[T], data: bytes) -> T:
|
||||
"""
|
||||
Parse the binary encoded Protobuf into this message instance. This
|
||||
returns the instance itself and is therefore assignable and chainable.
|
||||
|
||||
.. note::
|
||||
This is a method for compatibility with other libraries,
|
||||
you should really use :meth:`parse`.
|
||||
|
||||
|
||||
Parameters
|
||||
-----------
|
||||
data: :class:`bytes`
|
||||
The data to parse the protobuf from.
|
||||
|
||||
Returns
|
||||
--------
|
||||
:class:`Message`
|
||||
The initialized message.
|
||||
"""
|
||||
return cls().parse(data)
|
||||
|
||||
def to_dict(
|
||||
self, casing: Casing = Casing.CAMEL, include_default_values: bool = False
|
||||
) -> Dict[str, Any]:
|
||||
"""
|
||||
Returns a dict representation of this message instance which can be
|
||||
used to serialize to e.g. JSON. Defaults to camel casing for
|
||||
compatibility but can be set to other modes.
|
||||
Returns a JSON serializable dict representation of this object.
|
||||
|
||||
`include_default_values` can be set to `True` to include default
|
||||
values of fields. E.g. an `int32` type field with `0` value will
|
||||
not be in returned dict if `include_default_values` is set to
|
||||
`False`.
|
||||
Parameters
|
||||
-----------
|
||||
casing: :class:`Casing`
|
||||
The casing to use for key values. Default is :attr:`Casing.CAMEL` for
|
||||
compatibility purposes.
|
||||
include_default_values: :class:`bool`
|
||||
If ``True`` will include the default values of fields. Default is ``False``.
|
||||
E.g. an ``int32`` field will be included with a value of ``0`` if this is
|
||||
set to ``True``, otherwise this would be ignored.
|
||||
|
||||
Returns
|
||||
--------
|
||||
Dict[:class:`str`, Any]
|
||||
The JSON serializable dict representation of this object.
|
||||
"""
|
||||
output: Dict[str, Any] = {}
|
||||
field_types = self._type_hints()
|
||||
@@ -938,10 +1009,20 @@ class Message(ABC):
|
||||
output[cased_name] = value
|
||||
return output
|
||||
|
||||
def from_dict(self: T, value: dict) -> T:
|
||||
def from_dict(self: T, value: Dict[str, Any]) -> T:
|
||||
"""
|
||||
Parse the key/value pairs in `value` into this message instance. This
|
||||
returns the instance itself and is therefore assignable and chainable.
|
||||
Parse the key/value pairs into the current message instance. This returns the
|
||||
instance itself and is therefore assignable and chainable.
|
||||
|
||||
Parameters
|
||||
-----------
|
||||
value: Dict[:class:`str`, Any]
|
||||
The dictionary to parse from.
|
||||
|
||||
Returns
|
||||
--------
|
||||
:class:`Message`
|
||||
The initialized message.
|
||||
"""
|
||||
self._serialized_on_wire = True
|
||||
for key in value:
|
||||
@@ -998,28 +1079,70 @@ class Message(ABC):
|
||||
return self
|
||||
|
||||
def to_json(self, indent: Union[None, int, str] = None) -> str:
|
||||
"""Returns the encoded JSON representation of this message instance."""
|
||||
"""A helper function to parse the message instance into its JSON
|
||||
representation.
|
||||
|
||||
This is equivalent to::
|
||||
|
||||
json.dumps(message.to_dict(), indent=indent)
|
||||
|
||||
Parameters
|
||||
-----------
|
||||
indent: Optional[Union[:class:`int`, :class:`str`]]
|
||||
The indent to pass to :func:`json.dumps`.
|
||||
|
||||
Returns
|
||||
--------
|
||||
:class:`str`
|
||||
The JSON representation of the message.
|
||||
"""
|
||||
return json.dumps(self.to_dict(), indent=indent)
|
||||
|
||||
def from_json(self: T, value: Union[str, bytes]) -> T:
|
||||
"""
|
||||
Parse the key/value pairs in `value` into this message instance. This
|
||||
returns the instance itself and is therefore assignable and chainable.
|
||||
"""A helper function to return the message instance from its JSON
|
||||
representation. This returns the instance itself and is therefore assignable
|
||||
and chainable.
|
||||
|
||||
This is equivalent to::
|
||||
|
||||
return message.from_dict(json.loads(value))
|
||||
|
||||
Parameters
|
||||
-----------
|
||||
value: Union[:class:`str`, :class:`bytes`]
|
||||
The value to pass to :func:`json.loads`.
|
||||
|
||||
Returns
|
||||
--------
|
||||
:class:`Message`
|
||||
The initialized message.
|
||||
"""
|
||||
return self.from_dict(json.loads(value))
|
||||
|
||||
|
||||
def serialized_on_wire(message: Message) -> bool:
|
||||
"""
|
||||
True if this message was or should be serialized on the wire. This can
|
||||
be used to detect presence (e.g. optional wrapper message) and is used
|
||||
internally during parsing/serialization.
|
||||
If this message was or should be serialized on the wire. This can be used to detect
|
||||
presence (e.g. optional wrapper message) and is used internally during
|
||||
parsing/serialization.
|
||||
|
||||
Returns
|
||||
--------
|
||||
:class:`bool`
|
||||
Whether this message was or should be serialized on the wire.
|
||||
"""
|
||||
return message._serialized_on_wire
|
||||
|
||||
|
||||
def which_one_of(message: Message, group_name: str) -> Tuple[str, Any]:
|
||||
"""Return the name and value of a message's one-of field group."""
|
||||
"""
|
||||
Return the name and value of a message's one-of field group.
|
||||
|
||||
Returns
|
||||
--------
|
||||
Tuple[:class:`str`, Any]
|
||||
The field name and the value for that field.
|
||||
"""
|
||||
field_name = message._group_current.get(group_name)
|
||||
if not field_name:
|
||||
return ("", None)
|
||||
|
||||
@@ -21,14 +21,24 @@ def safe_snake_case(value: str) -> str:
|
||||
return value
|
||||
|
||||
|
||||
def snake_case(value: str, strict: bool = True):
|
||||
def snake_case(value: str, strict: bool = True) -> str:
|
||||
"""
|
||||
Join words with an underscore into lowercase and remove symbols.
|
||||
@param value: value to convert
|
||||
@param strict: force single underscores
|
||||
|
||||
Parameters
|
||||
-----------
|
||||
value: :class:`str`
|
||||
The value to convert.
|
||||
strict: :class:`bool`
|
||||
Whether or not to force single underscores.
|
||||
|
||||
Returns
|
||||
--------
|
||||
:class:`str`
|
||||
The value in snake_case.
|
||||
"""
|
||||
|
||||
def substitute_word(symbols, word, is_start):
|
||||
def substitute_word(symbols: str, word: str, is_start: bool) -> str:
|
||||
if not word:
|
||||
return ""
|
||||
if strict:
|
||||
@@ -52,11 +62,21 @@ def snake_case(value: str, strict: bool = True):
|
||||
return snake
|
||||
|
||||
|
||||
def pascal_case(value: str, strict: bool = True):
|
||||
def pascal_case(value: str, strict: bool = True) -> str:
|
||||
"""
|
||||
Capitalize each word and remove symbols.
|
||||
@param value: value to convert
|
||||
@param strict: output only alphanumeric characters
|
||||
|
||||
Parameters
|
||||
-----------
|
||||
value: :class:`str`
|
||||
The value to convert.
|
||||
strict: :class:`bool`
|
||||
Whether or not to output only alphanumeric characters.
|
||||
|
||||
Returns
|
||||
--------
|
||||
:class:`str`
|
||||
The value in PascalCase.
|
||||
"""
|
||||
|
||||
def substitute_word(symbols, word):
|
||||
@@ -77,14 +97,39 @@ def pascal_case(value: str, strict: bool = True):
|
||||
)
|
||||
|
||||
|
||||
def camel_case(value: str, strict: bool = True):
|
||||
def camel_case(value: str, strict: bool = True) -> str:
|
||||
"""
|
||||
Capitalize all words except first and remove symbols.
|
||||
|
||||
Parameters
|
||||
-----------
|
||||
value: :class:`str`
|
||||
The value to convert.
|
||||
strict: :class:`bool`
|
||||
Whether or not to output only alphanumeric characters.
|
||||
|
||||
Returns
|
||||
--------
|
||||
:class:`str`
|
||||
The value in camelCase.
|
||||
"""
|
||||
return lowercase_first(pascal_case(value, strict=strict))
|
||||
|
||||
|
||||
def lowercase_first(value: str):
|
||||
def lowercase_first(value: str) -> str:
|
||||
"""
|
||||
Lower cases the first character of the value.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
value: :class:`str`
|
||||
The value to lower case.
|
||||
|
||||
Returns
|
||||
-------
|
||||
:class:`str`
|
||||
The lower cased string.
|
||||
"""
|
||||
return value[0:1].lower() + value[1:]
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user