# deproto
<div align="center">
<img src="https://raw.githubusercontent.com/MrDebugger/deproto/main/assets/icons/DEPROTO.gif" alt="deproto logo" width="200"/>
</div>
<h4 align="center">A Python package for Google Maps protobuf format</h4>
<p align="center">
<a href="https://pypi.org/project/deproto/">
<img src="https://img.shields.io/pypi/v/deproto.svg" alt="PyPI version"/>
</a>
<a href="https://pypi.org/project/deproto/">
<img src="https://img.shields.io/pypi/pyversions/deproto.svg" alt="Python versions"/>
</a>
<a href="https://github.com/MrDebugger/deproto/blob/main/LICENSE">
<img src="https://img.shields.io/github/license/MrDebugger/deproto.svg" alt="License"/>
</a>
<a href="https://github.com/MrDebugger/deproto/stargazers">
<img src="https://img.shields.io/github/stars/MrDebugger/deproto.svg" alt="GitHub stars"/>
</a>
<a href="https://github.com/MrDebugger/deproto/network">
<img src="https://img.shields.io/github/forks/MrDebugger/deproto.svg" alt="GitHub forks"/>
</a>
<a href="https://github.com/MrDebugger/deproto/issues">
<img src="https://img.shields.io/github/issues/MrDebugger/deproto.svg" alt="GitHub issues"/>
</a>
<a href="https://pepy.tech/project/deproto">
<img src="https://pepy.tech/badge/deproto" alt="Downloads"/>
</a>
</p>
<p align="center">
<a href="https://github.com/MrDebugger/deproto#features">Features</a> •
<a href="https://github.com/MrDebugger/deproto#installation">Installation</a> •
<a href="https://github.com/MrDebugger/deproto#quick-start">Quick Start</a> •
<a href="https://github.com/MrDebugger/deproto#building-protobuf-structures">Documentation</a> •
<a href="https://github.com/MrDebugger/deproto#advanced-usage">Advanced</a> •
<a href="https://github.com/MrDebugger/deproto#testing">Testing</a>
</p>
A Python package for decoding, manipulating, and encoding Google Maps protobuf format strings. This library provides an intuitive way to work with protobuf structures commonly found in Google Maps URLs and data.
## Features
- Decode Google Maps protobuf strings into a tree structure
- Create and modify protobuf structures using multiple approaches
- Automatic type detection and handling
- Parent-child relationship tracking
- Automatic total count management in clusters
- Tree visualization for debugging
- Support for various data types
## Installation
Install using pip:
```bash
pip install -U deproto
```
## Quick Start
```python
from deproto import Protobuf
# Example protobuf string from Google Maps
pb_string = "!1m3!1s2024!2i42!3stest"
# Create decoder instance
decoder = Protobuf(pb_string)
# Decode the string into a tree structure
cluster = decoder.decode()
# Print the tree structure
decoder.print_tree()
# Make changes to values
cluster[1][1].change("2025")
# Encode back to protobuf format
encoded = decoder.encode()
```
## Building Protobuf Structures
There are multiple ways to build protobuf structures:
### 1. Direct Construction
```python
from deproto.cluster import Cluster
from deproto.node import Node
from deproto.types import StringType, IntType
# Create a structure directly
root = Cluster(1, [
Node(1, "hello", StringType()),
Cluster(2, [
Node(1, 42, IntType())
])
])
```
### 2. Using add() with Tuples
```python
root = Cluster(1)
root.add(1, [(1, "hello"), (2, 42)]) # Types auto-detected
```
### 3. Using add() with Nodes
```python
root = Cluster(1)
root.add(1, [
Node(1, "hello", StringType()),
Node(2, 42, IntType())
])
```
### 4. Mixed Approach
```python
root = Cluster(1)
root.add(1, Node(1, "hello", StringType()))
root.add(2, [(1, 42)]) # Type auto-detected
```
## Complex Structures
You can build complex nested structures:
```python
root = Cluster(1, [
Node(1, "metadata", StringType()),
Cluster(2, [
Node(1, 42, IntType()),
Node(2, True, BoolType()),
Cluster(3, [
Node(1, "nested", StringType()),
Node(2, 3.14, IntType())
])
]),
Node(3, "end", StringType())
])
```
## Tree Operations
### Finding and Replacing Nodes
You can find and replace nodes in the tree structure:
```python
from deproto import Protobuf, Cluster, Node
from deproto.types import StringType, IntType
# Create a sample cluster
cluster = Cluster(1, [
Node(1, "hello", StringType()),
Node(2, 42, IntType()),
Node(3, "world", StringType())
])
# Find a node by index
node = cluster.find(2) # Returns node with value 42
# Replace a node
new_node = Node(2, 100, IntType())
old_node = cluster.replace(2, new_node)
```
### JSON Serialization
The tree structure can be serialized into a simple list representation:
```python
from deproto import Protobuf, Cluster, Node
from deproto.types import StringType, IntType
# Create a simple structure
cluster = Cluster(1, [
Node(1, "test", StringType()),
Node(2, 42, IntType())
])
# Convert to list format
json_data = cluster.to_json()
print(json_data) # Output: ["test", 42]
# Create a nested structure
nested = Cluster(1, [
Node(1, "outer", StringType()),
Cluster(2, [
Node(1, "inner", StringType())
])
])
# Nested structures maintain hierarchy
nested_json = nested.to_json()
print(nested_json) # Output: ["outer", ["inner"]]
```
The `to_json()` method converts:
- Simple nodes into their values
- Clusters into lists of their children's values
- Maintains the nested structure of the tree
## Tree Visualization
The `print_tree()` method provides a clear visualization of the protobuf structure:
For example, given this protobuf string:
```
!1shello!6m4!4m1!1e1!5m1!1e1!2m2!1i42!2sworld!5m2!1sgreeting!7e1!8m5!1b1!2b1!3b1!5b1!7b1!11m4!1e1!2e2!3sen!4sGB!13m1!1e1
```
The tree visualization shows:
```
1m25 # Root cluster: index=1, total=25 clusters/nodes
├── 1shello # String node: "hello"
├── 6m4 # Cluster: index=6, total=4
│ ├── 4m1 # Nested cluster: index=4, total=1
│ │ └── 1e1 # Enum node: value=1
│ └── 5m1 # Another cluster: index=5, total=1
│ └── 1e1 # Enum node: value=1
├── 2m2 # Cluster: index=2, total=2
│ ├── 1i42 # Int node: value=42 (answer to everything)
│ └── 2sworld # String node: "world"
├── 5m2 # Cluster: index=5, total=2
│ ├── 1sgreeting # String node: "greeting"
│ └── 7e1 # Enum node: value=1
├── 8m5 # Cluster: index=8, total=5
│ ├── 1b1 # Bool node: true
│ ├── 2b1 # Bool node: true
│ ├── 3b1 # Bool node: true
│ ├── 5b1 # Bool node: true
│ └── 7b1 # Bool node: true
├── 11m4 # Cluster: index=11, total=4
│ ├── 1e1 # Enum node: value=1
│ ├── 2e2 # Enum node: value=2
│ ├── 3sen # String node: "en"
│ └── 4sGB # String node: "GB"
└── 13m1 # Cluster: index=13, total=1
└── 1e1 # Enum node: value=1
```
Understanding the numbers:
- First number is the index (1-based)
- `m` indicates a cluster, followed by total count
- Letters indicate type: `s`=string, `i`=int, `e`=enum, `b`=bool
Total count includes:
- Direct children nodes
- Nested clusters
- Children of nested clusters
For example, in `6m4`:
- Has 2 direct children (4m1 clusters)
- Each 4m1 cluster has 1 child (1e1 nodes)
- Total = 2 clusters + 2 nodes = 4
## Supported Data Types
| Type | Description | Example |
|------|-------------|---------|
| `B` | Bytes | Binary data |
| `b` | Boolean | True/False |
| `d` | Double | 3.14159 |
| `e` | Enum | 1, 2, 3 |
| `f` | Float | 3.14 |
| `i` | Int32/64 | 42 |
| `s` | String | "hello" |
| `x` | Fixed32 | 12345 |
| `y` | Fixed64 | 123456789 |
| `z` | Base64String | Encoded string |
## Advanced Usage
### Parent-Child Relationships
The library maintains parent-child relationships automatically:
```python
root = Cluster(1)
child = Cluster(2, [
Node(1, True, BoolType())
])
root.append(child)
assert child.parent == root
assert child[1].parent == child
```
### Automatic Total Management
Cluster totals are managed automatically when adding or removing nodes. The total includes both nodes and clusters:
```python
root = Cluster(1)
# Adding nodes in a cluster
root.add(1, [ # This creates: Cluster(1, [Node(1, "test"), Node(2, 42)])
Node(1, "test", StringType()),
Node(2, 42, IntType())
])
print(root.total) # 3 (1 for the cluster + 2 for the nodes)
# Adding a single node
root.add(2, Node(3, "direct", StringType()))
print(root.total) # 4 (previous 3 + 1 for the new node)
# Complex structure
root.add(3, [ # Creates nested clusters
Node(1, "hello", StringType()),
Cluster(2, [
Node(1, 42, IntType())
])
])
print(root.total) # 8 (previous 4 + 1 for new cluster + 1 for Node("hello")
# + 1 for inner Cluster + 1 for Node(42))
# Removing a cluster removes its total contribution
root.delete(3) # Removes the complex structure
print(root.total) # 4 (back to previous state)
```
Note: When using `add()` with a list, it creates a new cluster containing those items, which adds to the total count.
### Special Character Handling
String values with special characters are handled automatically:
```python
node = Node(1, "test!*", StringType())
print(node.value_raw) # "test*21*2A"
print(node.value) # "test!*"
```
## Testing
Run the test suite:
```bash
# Using pytest
pytest tests/
# With coverage
coverage run -m pytest tests/
coverage report
```
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
1. Fork the repository
2. Create your feature branch (`git checkout -b feature/AmazingFeature`)
3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)
4. Push to the branch (`git push origin feature/AmazingFeature`)
5. Open a Pull Request
## License
This project is licensed under the MIT License - see the [LICENSE](https://github.com/MrDebugger/deproto/blob/main/LICENSE) file for details.
## Author
Ijaz Ur Rahim ([ijazurrahim.com](https://ijazurrahim.com) | [@MrDebugger](https://github.com/MrDebugger))
## Current Version
**0.2.5** - See [CHANGELOG.md](https://github.com/MrDebugger/deproto/blob/main/CHANGELOG.md) for version history and details.
Raw data
{
"_id": null,
"home_page": "https://github.com/MrDebugger/deproto",
"name": "deproto",
"maintainer": "Ijaz Ur Rahim",
"docs_url": null,
"requires_python": ">=3.6",
"maintainer_email": "ijazkhan095@gmail.com",
"keywords": null,
"author": "Ijaz Ur Rahim",
"author_email": "ijazkhan095@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/31/92/2f3e2d4754ddc2006801ed99e6019e588f7f9c34c4646ac5de8b87683135/deproto-0.2.5.tar.gz",
"platform": null,
"description": "# deproto\n\n<div align=\"center\">\n <img src=\"https://raw.githubusercontent.com/MrDebugger/deproto/main/assets/icons/DEPROTO.gif\" alt=\"deproto logo\" width=\"200\"/>\n</div>\n\n<h4 align=\"center\">A Python package for Google Maps protobuf format</h4>\n\n<p align=\"center\">\n <a href=\"https://pypi.org/project/deproto/\">\n <img src=\"https://img.shields.io/pypi/v/deproto.svg\" alt=\"PyPI version\"/>\n </a>\n <a href=\"https://pypi.org/project/deproto/\">\n <img src=\"https://img.shields.io/pypi/pyversions/deproto.svg\" alt=\"Python versions\"/>\n </a>\n <a href=\"https://github.com/MrDebugger/deproto/blob/main/LICENSE\">\n <img src=\"https://img.shields.io/github/license/MrDebugger/deproto.svg\" alt=\"License\"/>\n </a>\n <a href=\"https://github.com/MrDebugger/deproto/stargazers\">\n <img src=\"https://img.shields.io/github/stars/MrDebugger/deproto.svg\" alt=\"GitHub stars\"/>\n </a>\n <a href=\"https://github.com/MrDebugger/deproto/network\">\n <img src=\"https://img.shields.io/github/forks/MrDebugger/deproto.svg\" alt=\"GitHub forks\"/>\n </a>\n <a href=\"https://github.com/MrDebugger/deproto/issues\">\n <img src=\"https://img.shields.io/github/issues/MrDebugger/deproto.svg\" alt=\"GitHub issues\"/>\n </a>\n <a href=\"https://pepy.tech/project/deproto\">\n <img src=\"https://pepy.tech/badge/deproto\" alt=\"Downloads\"/>\n </a>\n</p>\n\n<p align=\"center\">\n <a href=\"https://github.com/MrDebugger/deproto#features\">Features</a> \u2022\n <a href=\"https://github.com/MrDebugger/deproto#installation\">Installation</a> \u2022\n <a href=\"https://github.com/MrDebugger/deproto#quick-start\">Quick Start</a> \u2022\n <a href=\"https://github.com/MrDebugger/deproto#building-protobuf-structures\">Documentation</a> \u2022\n <a href=\"https://github.com/MrDebugger/deproto#advanced-usage\">Advanced</a> \u2022\n <a href=\"https://github.com/MrDebugger/deproto#testing\">Testing</a>\n</p>\n\nA Python package for decoding, manipulating, and encoding Google Maps protobuf format strings. This library provides an intuitive way to work with protobuf structures commonly found in Google Maps URLs and data.\n\n## Features\n\n- Decode Google Maps protobuf strings into a tree structure\n- Create and modify protobuf structures using multiple approaches\n- Automatic type detection and handling\n- Parent-child relationship tracking\n- Automatic total count management in clusters\n- Tree visualization for debugging\n- Support for various data types\n\n## Installation\n\nInstall using pip:\n\n```bash\npip install -U deproto\n```\n\n## Quick Start\n\n```python\nfrom deproto import Protobuf\n\n# Example protobuf string from Google Maps\npb_string = \"!1m3!1s2024!2i42!3stest\"\n\n# Create decoder instance\ndecoder = Protobuf(pb_string)\n\n# Decode the string into a tree structure\ncluster = decoder.decode()\n\n# Print the tree structure\ndecoder.print_tree()\n\n# Make changes to values\ncluster[1][1].change(\"2025\")\n\n# Encode back to protobuf format\nencoded = decoder.encode()\n```\n\n## Building Protobuf Structures\n\nThere are multiple ways to build protobuf structures:\n\n### 1. Direct Construction\n\n```python\nfrom deproto.cluster import Cluster\nfrom deproto.node import Node\nfrom deproto.types import StringType, IntType\n\n# Create a structure directly\nroot = Cluster(1, [\n Node(1, \"hello\", StringType()),\n Cluster(2, [\n Node(1, 42, IntType())\n ])\n])\n```\n\n### 2. Using add() with Tuples\n\n```python\nroot = Cluster(1)\nroot.add(1, [(1, \"hello\"), (2, 42)]) # Types auto-detected\n```\n\n### 3. Using add() with Nodes\n\n```python\nroot = Cluster(1)\nroot.add(1, [\n Node(1, \"hello\", StringType()),\n Node(2, 42, IntType())\n])\n```\n\n### 4. Mixed Approach\n\n```python\nroot = Cluster(1)\nroot.add(1, Node(1, \"hello\", StringType()))\nroot.add(2, [(1, 42)]) # Type auto-detected\n```\n\n## Complex Structures\n\nYou can build complex nested structures:\n\n```python\nroot = Cluster(1, [\n Node(1, \"metadata\", StringType()),\n Cluster(2, [\n Node(1, 42, IntType()),\n Node(2, True, BoolType()),\n Cluster(3, [\n Node(1, \"nested\", StringType()),\n Node(2, 3.14, IntType())\n ])\n ]),\n Node(3, \"end\", StringType())\n])\n```\n\n## Tree Operations\n\n### Finding and Replacing Nodes\n\nYou can find and replace nodes in the tree structure:\n\n```python\nfrom deproto import Protobuf, Cluster, Node\nfrom deproto.types import StringType, IntType\n\n# Create a sample cluster\ncluster = Cluster(1, [\n Node(1, \"hello\", StringType()),\n Node(2, 42, IntType()),\n Node(3, \"world\", StringType())\n])\n\n# Find a node by index\nnode = cluster.find(2) # Returns node with value 42\n\n# Replace a node\nnew_node = Node(2, 100, IntType())\nold_node = cluster.replace(2, new_node)\n```\n\n### JSON Serialization\n\nThe tree structure can be serialized into a simple list representation:\n\n```python\nfrom deproto import Protobuf, Cluster, Node\nfrom deproto.types import StringType, IntType\n\n# Create a simple structure\ncluster = Cluster(1, [\n Node(1, \"test\", StringType()),\n Node(2, 42, IntType())\n])\n\n# Convert to list format\njson_data = cluster.to_json()\nprint(json_data) # Output: [\"test\", 42]\n\n# Create a nested structure\nnested = Cluster(1, [\n Node(1, \"outer\", StringType()),\n Cluster(2, [\n Node(1, \"inner\", StringType())\n ])\n])\n\n# Nested structures maintain hierarchy\nnested_json = nested.to_json()\nprint(nested_json) # Output: [\"outer\", [\"inner\"]]\n```\n\nThe `to_json()` method converts:\n- Simple nodes into their values\n- Clusters into lists of their children's values\n- Maintains the nested structure of the tree\n\n## Tree Visualization\n\nThe `print_tree()` method provides a clear visualization of the protobuf structure:\n\nFor example, given this protobuf string:\n\n```\n!1shello!6m4!4m1!1e1!5m1!1e1!2m2!1i42!2sworld!5m2!1sgreeting!7e1!8m5!1b1!2b1!3b1!5b1!7b1!11m4!1e1!2e2!3sen!4sGB!13m1!1e1\n```\n\nThe tree visualization shows:\n\n```\n1m25 # Root cluster: index=1, total=25 clusters/nodes\n\u251c\u2500\u2500 1shello # String node: \"hello\"\n\u251c\u2500\u2500 6m4 # Cluster: index=6, total=4\n\u2502 \u251c\u2500\u2500 4m1 # Nested cluster: index=4, total=1\n\u2502 \u2502 \u2514\u2500\u2500 1e1 # Enum node: value=1\n\u2502 \u2514\u2500\u2500 5m1 # Another cluster: index=5, total=1\n\u2502 \u2514\u2500\u2500 1e1 # Enum node: value=1\n\u251c\u2500\u2500 2m2 # Cluster: index=2, total=2\n\u2502 \u251c\u2500\u2500 1i42 # Int node: value=42 (answer to everything)\n\u2502 \u2514\u2500\u2500 2sworld # String node: \"world\"\n\u251c\u2500\u2500 5m2 # Cluster: index=5, total=2\n\u2502 \u251c\u2500\u2500 1sgreeting # String node: \"greeting\"\n\u2502 \u2514\u2500\u2500 7e1 # Enum node: value=1\n\u251c\u2500\u2500 8m5 # Cluster: index=8, total=5\n\u2502 \u251c\u2500\u2500 1b1 # Bool node: true\n\u2502 \u251c\u2500\u2500 2b1 # Bool node: true\n\u2502 \u251c\u2500\u2500 3b1 # Bool node: true\n\u2502 \u251c\u2500\u2500 5b1 # Bool node: true\n\u2502 \u2514\u2500\u2500 7b1 # Bool node: true\n\u251c\u2500\u2500 11m4 # Cluster: index=11, total=4\n\u2502 \u251c\u2500\u2500 1e1 # Enum node: value=1\n\u2502 \u251c\u2500\u2500 2e2 # Enum node: value=2\n\u2502 \u251c\u2500\u2500 3sen # String node: \"en\"\n\u2502 \u2514\u2500\u2500 4sGB # String node: \"GB\"\n\u2514\u2500\u2500 13m1 # Cluster: index=13, total=1\n \u2514\u2500\u2500 1e1 # Enum node: value=1\n```\n\nUnderstanding the numbers:\n- First number is the index (1-based)\n- `m` indicates a cluster, followed by total count\n- Letters indicate type: `s`=string, `i`=int, `e`=enum, `b`=bool\n\nTotal count includes:\n- Direct children nodes\n- Nested clusters\n- Children of nested clusters\n\nFor example, in `6m4`:\n- Has 2 direct children (4m1 clusters)\n- Each 4m1 cluster has 1 child (1e1 nodes)\n- Total = 2 clusters + 2 nodes = 4\n\n## Supported Data Types\n\n| Type | Description | Example |\n|------|-------------|---------|\n| `B` | Bytes | Binary data |\n| `b` | Boolean | True/False |\n| `d` | Double | 3.14159 |\n| `e` | Enum | 1, 2, 3 |\n| `f` | Float | 3.14 |\n| `i` | Int32/64 | 42 |\n| `s` | String | \"hello\" |\n| `x` | Fixed32 | 12345 |\n| `y` | Fixed64 | 123456789 |\n| `z` | Base64String | Encoded string |\n\n## Advanced Usage\n\n### Parent-Child Relationships\n\nThe library maintains parent-child relationships automatically:\n\n```python\nroot = Cluster(1)\nchild = Cluster(2, [\n Node(1, True, BoolType())\n])\nroot.append(child)\n\nassert child.parent == root\nassert child[1].parent == child\n```\n\n### Automatic Total Management\n\nCluster totals are managed automatically when adding or removing nodes. The total includes both nodes and clusters:\n\n```python\nroot = Cluster(1)\n\n# Adding nodes in a cluster\nroot.add(1, [ # This creates: Cluster(1, [Node(1, \"test\"), Node(2, 42)])\n Node(1, \"test\", StringType()),\n Node(2, 42, IntType())\n])\nprint(root.total) # 3 (1 for the cluster + 2 for the nodes)\n\n# Adding a single node\nroot.add(2, Node(3, \"direct\", StringType()))\nprint(root.total) # 4 (previous 3 + 1 for the new node)\n\n# Complex structure\nroot.add(3, [ # Creates nested clusters\n Node(1, \"hello\", StringType()),\n Cluster(2, [\n Node(1, 42, IntType())\n ])\n])\nprint(root.total) # 8 (previous 4 + 1 for new cluster + 1 for Node(\"hello\")\n # + 1 for inner Cluster + 1 for Node(42))\n\n# Removing a cluster removes its total contribution\nroot.delete(3) # Removes the complex structure\nprint(root.total) # 4 (back to previous state)\n```\n\nNote: When using `add()` with a list, it creates a new cluster containing those items, which adds to the total count.\n\n### Special Character Handling\n\nString values with special characters are handled automatically:\n\n```python\nnode = Node(1, \"test!*\", StringType())\nprint(node.value_raw) # \"test*21*2A\"\nprint(node.value) # \"test!*\"\n```\n\n## Testing\n\nRun the test suite:\n\n```bash\n# Using pytest\npytest tests/\n\n# With coverage\ncoverage run -m pytest tests/\ncoverage report\n```\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n1. Fork the repository\n2. Create your feature branch (`git checkout -b feature/AmazingFeature`)\n3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)\n4. Push to the branch (`git push origin feature/AmazingFeature`)\n5. Open a Pull Request\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](https://github.com/MrDebugger/deproto/blob/main/LICENSE) file for details.\n\n## Author\n\nIjaz Ur Rahim ([ijazurrahim.com](https://ijazurrahim.com) | [@MrDebugger](https://github.com/MrDebugger))\n\n## Current Version\n\n**0.2.5** - See [CHANGELOG.md](https://github.com/MrDebugger/deproto/blob/main/CHANGELOG.md) for version history and details.\n",
"bugtrack_url": null,
"license": null,
"summary": "A decoder for Google Maps protobuf format",
"version": "0.2.5",
"project_urls": {
"Homepage": "https://github.com/MrDebugger/deproto",
"Source": "https://github.com/MrDebugger/deproto",
"Website": "https://ijazurrahim.com"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "c6a427037da005b5c29afbdcd02a2eebf482827af0a2b61c4844f8aa83db82f4",
"md5": "ea3ebed1b9dc557371b10ea0f02bdc0a",
"sha256": "10e8edb2aa9e527bc846c9b312e0499e36b8262d63a139a2d0e5474833b5093a"
},
"downloads": -1,
"filename": "deproto-0.2.5-py3-none-any.whl",
"has_sig": false,
"md5_digest": "ea3ebed1b9dc557371b10ea0f02bdc0a",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.6",
"size": 11732,
"upload_time": "2025-01-02T14:20:47",
"upload_time_iso_8601": "2025-01-02T14:20:47.712006Z",
"url": "https://files.pythonhosted.org/packages/c6/a4/27037da005b5c29afbdcd02a2eebf482827af0a2b61c4844f8aa83db82f4/deproto-0.2.5-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "31922f3e2d4754ddc2006801ed99e6019e588f7f9c34c4646ac5de8b87683135",
"md5": "1d8f62f1c848f96aef5e5f50d063a68c",
"sha256": "307331bc7be3cbedb9e9d27feaf60ff05b7b39458169cf42235c9d9bc4928c63"
},
"downloads": -1,
"filename": "deproto-0.2.5.tar.gz",
"has_sig": false,
"md5_digest": "1d8f62f1c848f96aef5e5f50d063a68c",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.6",
"size": 17164,
"upload_time": "2025-01-02T14:20:52",
"upload_time_iso_8601": "2025-01-02T14:20:52.619344Z",
"url": "https://files.pythonhosted.org/packages/31/92/2f3e2d4754ddc2006801ed99e6019e588f7f9c34c4646ac5de8b87683135/deproto-0.2.5.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-01-02 14:20:52",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "MrDebugger",
"github_project": "deproto",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "deproto"
}