{ "info": { "author": "Pavel Perestoronin", "author_email": "eigenein@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Topic :: Software Development :: Libraries", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "# `pure-protobuf`\n\nPython implementation of [Protocol Buffers](http://code.google.com/apis/protocolbuffers/docs/encoding.html) data types.\n\n[![Build Status](https://travis-ci.org/eigenein/protobuf.svg?branch=master)](https://travis-ci.org/eigenein/protobuf)\n[![Coverage Status](https://coveralls.io/repos/github/eigenein/protobuf/badge.svg?branch=master)](https://coveralls.io/github/eigenein/protobuf?branch=master)\n[![PyPI - Downloads](https://img.shields.io/pypi/dm/pure-protobuf.svg)](https://pypistats.org/packages/pure-protobuf)\n[![PyPI \u2013 Version](https://img.shields.io/pypi/v/pure-protobuf.svg)](https://pypi.org/project/pure-protobuf/#history)\n[![PyPI \u2013 Python](https://img.shields.io/pypi/pyversions/pure-protobuf.svg)](https://pypi.org/project/pure-protobuf/#files)\n[![License](https://img.shields.io/pypi/l/pure-protobuf.svg)](https://github.com/eigenein/protobuf/blob/master/LICENSE)\n\n## Dataclasses\n\n`pure-protobuf` allows you to take advantages of the standard [`dataclasses`](https://docs.python.org/3/library/dataclasses.html) module to define message types. It is preferred over the legacy interface for new projects. The dataclasses interface is available in Python 3.6 and higher.\n\nThe legacy interface is deprecated and still available via `pure_protobuf.legacy`.\n\nThis guide describes how to use `pure-protobuf` to structure your data. It tries to follow [the standard developer guide](https://developers.google.com/protocol-buffers/docs/proto3). It also assumes that you're familiar with Protocol Buffers.\n\n### Defining a message type\n\nLet's look at [the simple example](https://developers.google.com/protocol-buffers/docs/proto3#simple). Here's how it looks like in `proto3` syntax:\n\n```proto\nsyntax = \"proto3\";\n\nmessage SearchRequest {\n string query = 1;\n int32 page_number = 2;\n int32 result_per_page = 3;\n}\n```\n\nAnd this is how you define it with `pure-protobuf`:\n\n```python\n# Python 3.6+\n\nfrom dataclasses import dataclass\n\nfrom pure_protobuf.dataclasses_ import field, message\nfrom pure_protobuf.types import int32\n\n\n@message\n@dataclass\nclass SearchRequest:\n query: str = field(1, default='')\n page_number: int32 = field(2, default=int32(0))\n result_per_page: int32 = field(3, default=int32(0))\n\n\nassert SearchRequest(\n query='hello',\n page_number=int32(1),\n result_per_page=int32(10),\n).dumps() == b'\\x0A\\x05hello\\x10\\x01\\x18\\x0A'\n```\n\nKeep in mind that `@message` decorator should **always** stay on top of [`@dataclass`](https://docs.python.org/3/library/dataclasses.html#dataclasses.dataclass).\n\n### Serializing\n\nEach class wrapped with `@message` gets two methods attached:\n- `dumps() -> bytes` to serialize message into a byte string\n- `dump(io: IO)` to serialize message into a file-like object\n\n### Deserializing\n\nEach classes wrapped with `@message` gets two class methods attached:\n- `loads(bytes_: bytes) -> TMessage` to deserialize a message from a byte string\n- `load(io: IO) -> TMessage` to deserialize a message from a file-like object\n\nThese methods are also available as standalone functions in `pure_protobuf.dataclasses_`:\n- `load(cls: Type[T], io: IO) -> T`\n- `loads(cls: Type[T], bytes_: bytes) -> T`\n\n### Specifying field types\n\nIn `pure-protobuf` types are specified with [type hints](https://www.python.org/dev/peps/pep-0484/). Native Python `float`, `str`, `bytes` and `bool` types are supported. Since other Protocol Buffers types don't exist as native Python types, the package uses [`NewType`](https://docs.python.org/3/library/typing.html#newtype) to define them. They're available via `pure_protobuf.types` and named in the same way.\n\n### Assigning field numbers\n\nField numbers are provided via the `metadata` parameter of the [`field`](https://docs.python.org/3/library/dataclasses.html#dataclasses.field) function: `field(..., metadata={'number': number})`. However, to improve readability and save some characters, `pure-protobuf` provides a helper function `pure_protobuf.dataclasses_.field` which accepts field number as the first positional parameter and just passes it to the standard `field` function.\n\n### Specifying field rules\n\n[`typing.List`](https://docs.python.org/3/library/typing.html#typing.List) and [`typing.Iterable`](https://docs.python.org/3/library/typing.html#typing.Iterable) annotations are automatically converted to [repeated fields](https://developers.google.com/protocol-buffers/docs/proto3#specifying-field-rules). Repeated fields of scalar numeric types use packed encoding by default:\n\n```python\n# Python 3.6+\n\nfrom dataclasses import dataclass\nfrom typing import List\n\nfrom pure_protobuf.dataclasses_ import field, message\nfrom pure_protobuf.types import int32\n\n\n@message\n@dataclass\nclass Message:\n foo: List[int32] = field(1, default_factory=list)\n```\n\nIt's also possible to wrap a field type with [`typing.Optional`](https://docs.python.org/3/library/typing.html#typing.Optional). If `None` is assigned to an `Optional` field, then the field will be skipped during serialization.\n\n### Default values\n\nIn `pure-protobuf` it's developer's responsibility to take care of default values. If encoded message does not contain a particular element, the corresponding field stays unassigned. It means that the standard `default` and `default_factory` parameters of the `field` function work as usual:\n\n```python\n# Python 3.6+\n\nfrom dataclasses import dataclass\nfrom typing import Optional\n\nfrom pure_protobuf.dataclasses_ import field, message\nfrom pure_protobuf.types import int32\n\n\n@message\n@dataclass\nclass Foo:\n bar: int32 = field(1, default=42)\n qux: Optional[int32] = field(2, default=None)\n\n\nassert Foo().dumps() == b'\\x08\\x2A'\nassert Foo.loads(b'') == Foo(bar=42)\n```\n\nIn fact, the pattern `qux: Optional[int32] = field(2, default=None)` is so common that there's a convenience function `optional_field` to define an `Optional` field with `None` value by default:\n\n```python\n# Python 3.6+\n\nfrom dataclasses import dataclass\nfrom typing import Optional\n\nfrom pure_protobuf.dataclasses_ import optional_field, message\nfrom pure_protobuf.types import int32\n\n\n@message\n@dataclass\nclass Foo:\n qux: Optional[int32] = optional_field(2)\n\n\nassert Foo().dumps() == b''\nassert Foo.loads(b'') == Foo(qux=None)\n```\n\n### Enumerations\n\nSubclasses of the standard [`IntEnum`](https://docs.python.org/3/library/enum.html#intenum) class are supported:\n\n```python\n# Python 3.6+\n\nfrom dataclasses import dataclass\nfrom enum import IntEnum\n\nfrom pure_protobuf.dataclasses_ import field, message\n\n\nclass TestEnum(IntEnum):\n BAR = 1\n\n\n@message\n@dataclass\nclass Test:\n foo: TestEnum = field(1)\n\n\nassert Test(foo=TestEnum.BAR).dumps() == b'\\x08\\x01'\nassert Test.loads(b'\\x08\\x01') == Test(foo=TestEnum.BAR)\n```\n\n### Using other message types\n\nEmbedded messages are defined the same way as normal dataclasses:\n\n```python\n# Python 3.6+\n\nfrom dataclasses import dataclass\n\nfrom pure_protobuf.dataclasses_ import field, message\nfrom pure_protobuf.types import int32\n\n\n@message\n@dataclass\nclass Test1:\n a: int32 = field(1, default=0)\n\n\n@message\n@dataclass\nclass Test3:\n c: Test1 = field(3, default_factory=Test1)\n\n\nassert Test3(c=Test1(a=int32(150))).dumps() == b'\\x1A\\x03\\x08\\x96\\x01'\n```\n\n### Well-known message types\n\n`pure_protobuf.google` also provides built-in definitions for the following [well-known message types](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf):\n\n| Annotation | `pure_protobuf.types.google` | `.proto` |\n| ------------ | ---------------------------- | ----------- |\n| `datetime` | `Timestamp` | `Timestamp` |\n| `timedelta` | `Duration` | `Duration` |\n| `typing.Any` | `Any_` | `Any` |\n\nThey're handled automatically, you have nothing to do but use them normally in type hints:\n\n```python\n# Python 3.6+\n\nfrom dataclasses import dataclass\nfrom datetime import datetime\nfrom typing import Optional\n\nfrom pure_protobuf.dataclasses_ import field, message\n\n\n@message\n@dataclass\nclass Test:\n timestamp: Optional[datetime] = field(1, default=None)\n```\n\n#### [`Any`](https://developers.google.com/protocol-buffers/docs/proto3#any)\n\nSince `pure-protobuf` is not able to download or parse `.proto` definitions, it provides a limited implementation of the [`Any`](https://developers.google.com/protocol-buffers/docs/proto3#any) message type. That is, you still have to define all message classes in the usual way. Then, `pure-protobuf` will be able to import and instantiate an encoded value:\n\n```python\n# Python 3.6+\n\nfrom dataclasses import dataclass\nfrom typing import Any, Optional\n\nfrom pure_protobuf.dataclasses_ import field, message\nfrom pure_protobuf.types.google import Timestamp\n\n\n@message\n@dataclass\nclass Message:\n value: Optional[Any] = field(1)\n\n\n# Here `Timestamp` is used just as an example, in principle any importable user type works.\nmessage = Message(value=Timestamp(seconds=42))\nassert Message.loads(message.dumps()) == message\n```\n\n## Legacy interface\n\n**The legacy interface is deprecated and stays in \"maintanance mode\" for Python 2 users. It will be removed one day. New projects should strongly consider using the dataclasses.**\n\nAssume you have the following definition:\n\n```proto\nmessage Test2 {\n string b = 2;\n}\n```\n\nThis is how you can create a message and get it serialized:\n\n```python\nfrom io import BytesIO\n\nfrom pure_protobuf.legacy import MessageType, Unicode\n\n# Create the type instance and add the field.\ntype_ = MessageType()\ntype_.add_field(2, 'b', Unicode)\n\nmessage = type_()\nmessage.b = 'testing'\n\n# Dump into a string.\nassert message.dumps() == b'\\x12\\x07testing'\n\n# Dump into a file-like object.\nfp = BytesIO()\nmessage.dump(fp)\n\n# Load from a string.\nassert type_.loads(message.dumps()) == message\n\n# Load from a file-like object.\nfp.seek(0)\nassert type_.load(fp) == message\n```\n\n### Required field\n\nTo add a missing field you should pass an additional `flags` parameter to `add_field` like this:\n\n```python\nfrom pure_protobuf.legacy import Flags, MessageType, Unicode\n\ntype_ = MessageType()\ntype_.add_field(2, 'b', Unicode, flags=Flags.REQUIRED)\n\nmessage = type_()\nmessage.b = 'hello, world'\n\nassert type_.dumps(message)\n```\n\nIf you'll not fill in a required field, then `ValueError` will be raised during serialization.\n\n### Repeated field\n\n```python\nfrom pure_protobuf.legacy import Flags, MessageType, UVarint\n\ntype_ = MessageType()\ntype_.add_field(1, 'b', UVarint, flags=Flags.REPEATED)\n\nmessage = type_()\nmessage.b = (1, 2, 3)\n\nassert type_.dumps(message)\n```\n\nValue of a repeated field can be any iterable object. The loaded value will always be `list`.\n\n### Packed repeated field\n\n```python\nfrom pure_protobuf.legacy import Flags, MessageType, UVarint\n\ntype_ = MessageType()\ntype_.add_field(4, 'd', UVarint, flags=Flags.PACKED_REPEATED)\n\nmessage = type_()\nmessage.d = (3, 270, 86942)\n\nassert type_.dumps(message)\n```\n\n### Embedded messages\n\n```proto\nmessage Test1 {\n int32 a = 1;\n}\n\nmessage Test3 {\n required Test1 c = 3;\n}\n```\n\nTo create an embedded field, wrap inner type with `EmbeddedMessage`:\n\n```python\nfrom pure_protobuf.legacy import EmbeddedMessage, MessageType, UVarint\n\ninner_type = MessageType()\ninner_type.add_field(1, 'a', UVarint)\nouter_type = MessageType()\nouter_type.add_field(3, 'c', EmbeddedMessage(inner_type))\n\nmessage = outer_type()\nmessage.c = inner_type()\nmessage.c.a = 150\n\nassert outer_type.dumps(message)\n```\n\n### Data types\n\n| Type | Python | Description |\n|-----------|---------|------------------------------------|\n| `UVarint` | `int` | unsigned integer (variable length) |\n| `Varint` | `int` | signed integer (variable length) |\n| `Bool` | `bool` | boolean |\n| `Fixed64` | `bytes` | 8-byte string |\n| `UInt64` | `int` | C 64-bit `unsigned long long` |\n| `Int64` | `int` | C 64-bit `long long` |\n| `Float64` | `float` | C `double` |\n| `Fixed32` | `bytes` | 4-byte string |\n| `UInt32` | `int` | C 32-bit `unsigned int` |\n| `Int32` | `int` | C 32-bit `int` |\n| `Float32` | `float` | C `float` |\n| `Bytes` | `bytes` | byte string |\n| `Unicode` | `str` | unicode string |\n\n### Some techniques\n\n#### Streaming messages\n\nThe Protocol Buffers format is not self-delimiting. But you can wrap your message type with `EmbeddedMessage` and write or read messages sequentially.\n\n#### `add_field` chaining\n\n`add_field` return the message type itself, thus you can do so:\n\n```python\nfrom pure_protobuf.legacy import EmbeddedMessage, MessageType, UVarint\n\nMessageType().add_field(1, 'a', EmbeddedMessage(MessageType().add_field(1, 'a', UVarint)))\n```\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/eigenein/protobuf", "keywords": "", "license": "", "maintainer": "", "maintainer_email": "", "name": "pure-protobuf", "package_url": "https://pypi.org/project/pure-protobuf/", "platform": "", "project_url": "https://pypi.org/project/pure-protobuf/", "project_urls": { "Homepage": "https://github.com/eigenein/protobuf" }, "release_url": "https://pypi.org/project/pure-protobuf/1.2.0/", "requires_dist": [ "dataclasses (<1.0,>=0.6) ; python_version >= \"3.6\" and python_version < \"3.7\"", "flake8 ; extra == 'dev'", "isort ; extra == 'dev'", "pytest ; extra == 'dev'", "pytest-cov ; extra == 'dev'", "coveralls ; extra == 'dev'" ], "requires_python": "", "summary": "Python implementation of Protocol Buffers data types with dataclasses support", "version": "1.2.0" }, "last_serial": 5476501, "releases": { "0.4.0": [ { "comment_text": "", "digests": { "md5": "497af341ac99974d242de11150f06994", "sha256": "fcee6c32bd7fca9b579ab0311e27f7a18f4299cf90f518b8031b141c6b13ead4" }, "downloads": -1, "filename": "pure_protobuf-0.4.0-py2-none-any.whl", "has_sig": false, "md5_digest": "497af341ac99974d242de11150f06994", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 8461, "upload_time": "2018-12-15T13:21:11", "url": "https://files.pythonhosted.org/packages/f2/69/b74ea0b532152be9fcce09ec308373ac3fce5c5c1d95a464d0cb6f043e63/pure_protobuf-0.4.0-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "ec632399a0a0cbe892242cb948683b08", "sha256": "710b2d8b04d27ef3b4bbb8c5a9eae431308d1839432ddd01ef44a1d5d050ad4a" }, "downloads": -1, "filename": "pure-protobuf-0.4.0.tar.gz", "has_sig": false, "md5_digest": "ec632399a0a0cbe892242cb948683b08", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7310, "upload_time": "2018-12-15T13:21:13", "url": "https://files.pythonhosted.org/packages/76/de/9e5b6dcb7e30d0def952e5eb8f37026c9d85c4de1d3f8fe306721715076e/pure-protobuf-0.4.0.tar.gz" } ], "0.4.1": [ { "comment_text": "", "digests": { "md5": "b7fb5b55bf1898f68919ae8689b6378e", "sha256": "a49a65152e163005c00534103097c1c1643940fb18f60868b64f7c444e3bffe7" }, "downloads": -1, "filename": "pure_protobuf-0.4.1-py2-none-any.whl", "has_sig": false, "md5_digest": "b7fb5b55bf1898f68919ae8689b6378e", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 8314, "upload_time": "2019-01-08T16:58:35", "url": "https://files.pythonhosted.org/packages/fd/f2/28332603d58f8388e4120f4ad9967e4f10f161185e3f81acbf1aa689afd7/pure_protobuf-0.4.1-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "4889dca3c85d638ab8c657022127913b", "sha256": "02c1c35529662426ced05c4689ce57fc8acd267c760dbc9367c32bdf5c9fd3db" }, "downloads": -1, "filename": "pure-protobuf-0.4.1.tar.gz", "has_sig": false, "md5_digest": "4889dca3c85d638ab8c657022127913b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8817, "upload_time": "2019-01-08T16:58:36", "url": "https://files.pythonhosted.org/packages/c8/97/5f8ce0747fe27a73c1464b3bbd39f8150dcdfc4180b9a4d545edca8fbc80/pure-protobuf-0.4.1.tar.gz" } ], "0.5.0": [ { "comment_text": "", "digests": { "md5": "1bb831de72f4335ea5d6bac40000e40b", "sha256": "ce61841fad78ac470d089c5baa1cccb8da8544f4c058fcd15ecb4f9600a4b927" }, "downloads": -1, "filename": "pure_protobuf-0.5.0-py3-none-any.whl", "has_sig": false, "md5_digest": "1bb831de72f4335ea5d6bac40000e40b", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 7797, "upload_time": "2019-03-13T22:39:19", "url": "https://files.pythonhosted.org/packages/01/3b/44131124dd489dcfc0f728ec530fdf42deea95037bd7458dfd7ce3f695a4/pure_protobuf-0.5.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "a51a77ff096fb86d2c17d669a4cd5ff0", "sha256": "83f67d73d49e03011bc0118f96e20b4e352141be400a6b961ce76b91ae595252" }, "downloads": -1, "filename": "pure-protobuf-0.5.0.tar.gz", "has_sig": false, "md5_digest": "a51a77ff096fb86d2c17d669a4cd5ff0", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7369, "upload_time": "2019-03-13T22:39:21", "url": "https://files.pythonhosted.org/packages/e0/ae/0d4b62c045be161aae6b2db09040f392ffcf9b8c8617bbb0c941402f7f6b/pure-protobuf-0.5.0.tar.gz" } ], "1.0.0": [ { "comment_text": "", "digests": { "md5": "c58dccf34d179c3ad33f6d6dcfe88569", "sha256": "167eb8b1a40579a716a6538bee748e1b1a9869fb3e686b5d208b100f9bb21668" }, "downloads": -1, "filename": "pure_protobuf-1.0.0-py3-none-any.whl", "has_sig": false, "md5_digest": "c58dccf34d179c3ad33f6d6dcfe88569", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 22519, "upload_time": "2019-03-31T21:16:31", "url": "https://files.pythonhosted.org/packages/bc/1c/214c051356db211f98081f955053e3e005603be7bc61b761e954a83188a4/pure_protobuf-1.0.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "4d030590f1889805fd1431d8163b72fa", "sha256": "e50c0d89990055562309c20d60c8a09e2a7bdbe64309eff8ea6aa4c975e052fc" }, "downloads": -1, "filename": "pure-protobuf-1.0.0.tar.gz", "has_sig": false, "md5_digest": "4d030590f1889805fd1431d8163b72fa", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17837, "upload_time": "2019-03-31T21:16:33", "url": "https://files.pythonhosted.org/packages/31/58/02f6596938ed0f934ff4803b48f1758ae90869229923264b83b82e40245c/pure-protobuf-1.0.0.tar.gz" } ], "1.0.1": [ { "comment_text": "", "digests": { "md5": "90afd16171e5c4581dd8e97f817cfb5e", "sha256": "cca575614de01660badbd6837625cffe631ef1946a366011ed8304200cd6558d" }, "downloads": -1, "filename": "pure_protobuf-1.0.1-py3-none-any.whl", "has_sig": false, "md5_digest": "90afd16171e5c4581dd8e97f817cfb5e", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 22576, "upload_time": "2019-04-16T13:40:33", "url": "https://files.pythonhosted.org/packages/4d/93/2665e23f36c81744c6dcaebbeca79e2f613199e6b48c791e27fc91135405/pure_protobuf-1.0.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "5fd4295ce6c1308aca02a252757dbaae", "sha256": "a0a6764891728805c97b668829cded1a2362e6ffdd72295c2cd497e22e17e2cf" }, "downloads": -1, "filename": "pure-protobuf-1.0.1.tar.gz", "has_sig": false, "md5_digest": "5fd4295ce6c1308aca02a252757dbaae", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17882, "upload_time": "2019-04-16T13:40:35", "url": "https://files.pythonhosted.org/packages/1d/36/50b88e1749fd8add23d77cc60352abdb2ffeb9de6c8e933245679f3c557f/pure-protobuf-1.0.1.tar.gz" } ], "1.1.0": [ { "comment_text": "", "digests": { "md5": "e3dabcab3c3669647a078afbf5bfee21", "sha256": "a8ac2c4dd373c2b5bb3c20fbdf109c560c261dc9559d8a004107944cadea4112" }, "downloads": -1, "filename": "pure_protobuf-1.1.0-py3-none-any.whl", "has_sig": false, "md5_digest": "e3dabcab3c3669647a078afbf5bfee21", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 28838, "upload_time": "2019-04-24T19:44:08", "url": "https://files.pythonhosted.org/packages/b5/6e/386e02cc87ff59aba131e0933c06b14f7f86911a06bf012845c4cae080e2/pure_protobuf-1.1.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "61b2ce9abcd148dd1f142893b10c4cb8", "sha256": "b049dd3631b733c698bfd1b7a3ce612bdec6f7daeb549ded7cc2b57ff527d6a7" }, "downloads": -1, "filename": "pure-protobuf-1.1.0.tar.gz", "has_sig": false, "md5_digest": "61b2ce9abcd148dd1f142893b10c4cb8", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 19821, "upload_time": "2019-04-24T19:44:12", "url": "https://files.pythonhosted.org/packages/cb/87/61c6e2ea2ff389f31bc44a27d73479eae3e39c6c32a57f8b92dfc79a17a3/pure-protobuf-1.1.0.tar.gz" } ], "1.2.0": [ { "comment_text": "", "digests": { "md5": "6df7e698bd256fa1225f864f5a6321dd", "sha256": "d045779a29f5ae4dd1641b5f9fd1aa04e9de764001643636aa88617850c2b8d6" }, "downloads": -1, "filename": "pure_protobuf-1.2.0-py3-none-any.whl", "has_sig": false, "md5_digest": "6df7e698bd256fa1225f864f5a6321dd", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 21478, "upload_time": "2019-07-02T11:38:50", "url": "https://files.pythonhosted.org/packages/98/11/5dc29229b573370eb2a21fe7c5d063fff7abebee7ef008b31612ba6b3493/pure_protobuf-1.2.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "bbdffdd440e518f9329f437641acb9e1", "sha256": "4dc22aa271f866c185736948c78a6d7fc91da284f9f2b38571be71af820a0033" }, "downloads": -1, "filename": "pure-protobuf-1.2.0.tar.gz", "has_sig": false, "md5_digest": "bbdffdd440e518f9329f437641acb9e1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 20369, "upload_time": "2019-07-02T11:38:54", "url": "https://files.pythonhosted.org/packages/9a/56/bc1cad5cc23b51db12c0837b14aedd5c902bc360fbb9089ee65a1c56cee4/pure-protobuf-1.2.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "6df7e698bd256fa1225f864f5a6321dd", "sha256": "d045779a29f5ae4dd1641b5f9fd1aa04e9de764001643636aa88617850c2b8d6" }, "downloads": -1, "filename": "pure_protobuf-1.2.0-py3-none-any.whl", "has_sig": false, "md5_digest": "6df7e698bd256fa1225f864f5a6321dd", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 21478, "upload_time": "2019-07-02T11:38:50", "url": "https://files.pythonhosted.org/packages/98/11/5dc29229b573370eb2a21fe7c5d063fff7abebee7ef008b31612ba6b3493/pure_protobuf-1.2.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "bbdffdd440e518f9329f437641acb9e1", "sha256": "4dc22aa271f866c185736948c78a6d7fc91da284f9f2b38571be71af820a0033" }, "downloads": -1, "filename": "pure-protobuf-1.2.0.tar.gz", "has_sig": false, "md5_digest": "bbdffdd440e518f9329f437641acb9e1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 20369, "upload_time": "2019-07-02T11:38:54", "url": "https://files.pythonhosted.org/packages/9a/56/bc1cad5cc23b51db12c0837b14aedd5c902bc360fbb9089ee65a1c56cee4/pure-protobuf-1.2.0.tar.gz" } ] }