Skip to content

Commit

Permalink
generate stubs for grpclib (#12)
Browse files Browse the repository at this point in the history
* restyling

* generate stubs for grpclib

grpclib is a pure-python grpc library at https://github.com/vmagamedov/grpclib

because grpcio generates stubs into [name]_pb2_grpc.py, and grpclib generates
stubs into [name]_grpc.py, both stubs can coexist peacefully in the same
package, although it would be clearer to rename the files based on the backend
they assume is present.

* Restyled by autopep8

* Restyled by black

* Restyled by isort

* Restyled by prettier-markdown

* Restyled by yapf

---------

Co-authored-by: Restyled.io <commits@restyled.io>
  • Loading branch information
xloem and restyled-commits authored Jul 23, 2023
1 parent 6d8d0ce commit 13b26af
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 52 deletions.
48 changes: 30 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
# Cosmos Protobuf

This repository compains the whole cosmos protobuf files compiled for python and ready to use with grpc. Please use the according .proto file as documentation for each python file.

## Installation

You can install this package directly from the repository by using:

```
python -m pip install cosmospy-protobuf
```

## Usage

The following code snippet will query the balances for the address ``osmo15hzhcvgs2ljfng6unghvr5l32prwqdyq4aguxn``. The according query.proto file in the bank subdirectory contains the Request and the Response for this request. The details for the response are defined in ``QueryAllBalancesResponse``. It contains the balances and pagination attribute which can be accessed as shown in the example below.
The following code snippet will query the balances for the address `osmo15hzhcvgs2ljfng6unghvr5l32prwqdyq4aguxn`. The according query.proto file in the bank subdirectory contains the Request and the Response for this request. The details for the response are defined in `QueryAllBalancesResponse`. It contains the balances and pagination attribute which can be accessed as shown in the example below.

```python
import grpc
import cosmospy_protobuf.cosmos.bank.v1beta1.query_pb2_grpc as query_pb2_grpc
import grpc # using grpcio
import cosmospy_protobuf.cosmos.bank.v1beta1.query_pb2_grpc as query_pb2_grpc # for gprcio
#import cosmospy_protobuf.cosmos.bank.v1beta1.query_grpc as query_grpc # for gprclib
import cosmospy_protobuf.cosmos.bank.v1beta1.query_pb2 as query_pb2

host = "osmosis.strange.love"
Expand All @@ -29,39 +32,48 @@ print(r.balances)
```

## Build yourself

There are two scripts helping you to fork this repository to work with any cosmos based coin.

Addititional Requirements:

1. `grpcio-tools`
2. `GitPython`
3. `protoletariat`
2. `grpclib`
3. `GitPython`
4. `protoletariat`

Steps:
1. Create a config in ``configs`` and take a existing one as example
2. Run the ``aggregate.py`` file with your filename without ``.json`` (Example ``python aggregate.py cosmos``)
3. Run the ``compile.py`` to compile all your files to protobuf

1. Create a config in `configs` and take a existing one as example
2. Run the `aggregate.py` file with your filename without `.json` (Example `python aggregate.py cosmos`)
3. Run the `compile.py` to compile all your files to protobuf
4. Build your package. You're done!

## Protobuf compilation
## Protobuf compilation

The files are compiled using the ``grpc_tools.protoc`` command from the [grpcio-tools](https://pypi.org/project/grpcio-tools/) library.
The files are compiled using the `grpc_tools.protoc` command from the [grpcio-tools](https://pypi.org/project/grpcio-tools/) library.
To compile a .proto file manually use following command:

```
python -m grpc_tools.protoc -I <absolute path to project root> --python_out=. --grpc_python_out=. <absolute path to .proto file>
python -m grpc_tools.protoc -I <absolute path to project root> --python_out=. --grpc_python_out=. --grpclib_python_out=. <absolute path to .proto file>
```

After compiling all the files with protoc you need to fix the imports by using [protoletariat](https://github.com/cpcloud/protoletariat)

Note:
* The --grpc_python_out=. is only needed when compiling a query.proto file as these define the actual grpc query
* To compile the whole project it is favorable to match all proto files by using `*.proto` instead of each individual file. You can also match the whole folders to compile multiple folders at the same time. Not that the folders might contain sub-folders.

- The --grpc_python_out=. and --grpclib_python_out=. is only needed when compiling a query.proto file as these define the actual grpc query
- To compile the whole project it is favorable to match all proto files by using `*.proto` instead of each individual file. You can also match the whole folders to compile multiple folders at the same time. Not that the folders might contain sub-folders.

## Other Cosmos based coins

Currently following coins are maintained by me:
* Cosmos (this branch)
* Evmos (branch: ``chain/evmos``, package name: ``evmos-protobuf``)
* Osmosis (branch: ``chain/osmosis``, package name: `osmosis-protobuf`)
* Stargaze (branch: ``chain/stargaze``, package name: `stargaze-protobuf`)

- Cosmos (this branch)
- Evmos (branch: `chain/evmos`, package name: `evmos-protobuf`)
- Osmosis (branch: `chain/osmosis`, package name: `osmosis-protobuf`)
- Stargaze (branch: `chain/stargaze`, package name: `stargaze-protobuf`)

Maintained by external contributors:
* Sentinel (branch: ``chain/sentinel``, package name: `sentinel-protobuf`)

- Sentinel (branch: `chain/sentinel`, package name: `sentinel-protobuf`)
114 changes: 80 additions & 34 deletions compile.py
Original file line number Diff line number Diff line change
@@ -1,87 +1,133 @@
import argparse
import logging
import os
import re
import subprocess
import sys
import logging

parser = argparse.ArgumentParser(description='Aggregate all protobuf files')
parser.add_argument('-p', '--package_name', type=str, default="cosmospy_protobuf", help="Name for the package to build. This will aggregate all files in the src/{package_name} folder")
parser = argparse.ArgumentParser(description="Aggregate all protobuf files")
parser.add_argument(
"-p",
"--package_name",
type=str,
default="cosmospy_protobuf",
help=
"Name for the package to build. This will aggregate all files in the src/{package_name} folder",
)
args = parser.parse_args()


package_name = 'src/' + args.package_name
logging.basicConfig(format='%(asctime)s - %(levelname)s:%(message)s', level=logging.DEBUG)
package_name = "src/" + args.package_name
logging.basicConfig(format="%(asctime)s - %(levelname)s:%(message)s",
level=logging.DEBUG)
absolute_path = os.path.abspath(package_name)


def run_protoc(filepath):
if os.path.basename(filepath) == "query.proto" or os.path.basename(filepath) == "service.proto":
cmd = [sys.executable, '-m', 'grpc_tools.protoc',
'--proto_path', absolute_path,
'--python_out', package_name,
'--pyi_out', package_name,
'--grpc_python_out', package_name,
filepath]
if (os.path.basename(filepath) == "query.proto"
or os.path.basename(filepath) == "service.proto"):
cmd = [
sys.executable,
"-m",
"grpc_tools.protoc",
"--proto_path",
absolute_path,
"--python_out",
package_name,
"--pyi_out",
package_name,
"--grpc_python_out",
package_name,
"--grpclib_python_out",
package_name,
filepath,
]
logging.info(f"Compiling proto and grpc file: {filepath}")
else:
cmd = [sys.executable, '-m', 'grpc_tools.protoc',
f'--proto_path={absolute_path}',
f'--python_out={package_name}',
f'--pyi_out={package_name}',
filepath]
cmd = [
sys.executable,
"-m",
"grpc_tools.protoc",
f"--proto_path={absolute_path}",
f"--python_out={package_name}",
f"--pyi_out={package_name}",
filepath,
]
logging.info(f"Compiling proto file: {filepath}")

subprocess.run(cmd)


def fix_proto_imports(filepath):
logging.info(f"Fixing file at: {filepath}")
cmd = [sys.executable, '-m', 'protoletariat',
'--create-package', '--in-place',
'--python-out', package_name,
'protoc', f'--proto-path={absolute_path}',
filepath]
cmd = [
sys.executable,
"-m",
"protoletariat",
"--create-package",
"--in-place",
"--python-out",
package_name,
"--module-suffixes",
"_pb2.py",
"--module-suffixes",
"_pb2.pyi",
"--module-suffixes",
"_pb2_grpc.py",
"--module-suffixes",
"_pb2_grpc.pyi",
"--module-suffixes",
"_grpc.py",
"--module-suffixes",
"_grpc.pyi",
"protoc",
f"--proto-path={absolute_path}",
filepath,
]
subprocess.run(cmd)


def walk_through_project_and_compile_proto(directory):
for root, dirs, files in os.walk(directory):
for filename in files:
if filename.endswith('.proto'):
if filename.endswith(".proto"):
run_protoc(os.path.abspath(os.path.join(root, filename)))


def walk_through_project_and_fix_imports(directory):
for root, dirs, files in os.walk(directory):
for filename in files:
if filename.endswith('.proto'):
fix_proto_imports(os.path.abspath(os.path.join(root, filename)))
if filename.endswith(".proto"):
fix_proto_imports(os.path.abspath(os.path.join(root,
filename)))
logging.info(f"Fixed imports for {filename}")


def remove_all_compiled_python_files(directory):
for root, dirs, files in os.walk(directory):
for filename in files:
if filename.endswith('.py') or filename.endswith('.pyi'):
if filename.endswith(".py") or filename.endswith(".pyi"):
logging.info(f"Deleting {os.path.join(root, filename)}")
os.remove(os.path.join(root, filename))


def rename_any_proto_imports(directory):
for root, dirs, files in os.walk(directory):
for filename in files:
with open(os.path.join(root, filename), 'r') as file:
with open(os.path.join(root, filename), "r") as file:
lines = file.readlines()

if 'import "google/protobuf/any.proto";\n' in lines:
with open(os.path.join(root, filename), 'w') as file:
with open(os.path.join(root, filename), "w") as file:
for line in lines:
file.write(re.sub(r'^import "google/protobuf/any.proto";\n', 'import "google/protobuf/cosmos_any.proto";\n', line))



file.write(
re.sub(
r'^import "google/protobuf/any.proto";\n',
'import "google/protobuf/cosmos_any.proto";\n',
line,
))


#rename_any_proto_imports(package_name)
# rename_any_proto_imports(package_name)
remove_all_compiled_python_files(package_name)
walk_through_project_and_compile_proto(package_name)
walk_through_project_and_fix_imports(package_name)

0 comments on commit 13b26af

Please sign in to comment.