{"id":15877829,"url":"https://github.com/oseiskar/protowire","last_synced_at":"2025-11-02T00:03:31.266Z","repository":{"id":48084906,"uuid":"92428758","full_name":"oseiskar/protowire","owner":"oseiskar","description":"Write protobuf messages \u0026 GRPC calls from the command line without the proto files","archived":false,"fork":false,"pushed_at":"2021-08-07T19:12:01.000Z","size":38,"stargazers_count":5,"open_issues_count":1,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-27T05:23:17.403Z","etag":null,"topics":["command-line-tool","grpc","protobuf","protocol-buffers","python"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/oseiskar.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-05-25T17:43:47.000Z","updated_at":"2021-08-07T19:05:48.000Z","dependencies_parsed_at":"2022-07-28T23:08:45.098Z","dependency_job_id":null,"html_url":"https://github.com/oseiskar/protowire","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oseiskar%2Fprotowire","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oseiskar%2Fprotowire/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oseiskar%2Fprotowire/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oseiskar%2Fprotowire/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/oseiskar","download_url":"https://codeload.github.com/oseiskar/protowire/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243806032,"owners_count":20350773,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["command-line-tool","grpc","protobuf","protocol-buffers","python"],"created_at":"2024-10-06T02:04:09.885Z","updated_at":"2025-11-02T00:03:31.219Z","avatar_url":"https://github.com/oseiskar.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n\n# Protowire [![PyPI](https://img.shields.io/pypi/v/protowire.svg)](https://pypi.python.org/pypi/protowire)\n\nWrite protobuf messages from the command line:\n\n    pw (field number) [data type] (value) \u003e output.bin\n\nwhere `data type` is one of the [protobuf datatypes](https://developers.google.com/protocol-buffers/docs/proto3#scalar) (or `int` = `int32` = `int64`). If `value` is not given, it is read from STDIN.\nThe field number can be left out and defaults to 1.\n\nThis enables creating protobuf messages for GRPC calls or other purposes without a protobuf compiler. The `pw` tool has no library dependencies (plain Python) and does not need the `.proto` files or any code generated from them.\n\n### Installation\n\n    sudo pip install protowire\n\n### Examples\n\nTo write a protobuf message conforming to, e.g., `message Test1 { int32 a = 1; }` such that `a` has the value 150, write\n\n    pw 1 int32 150 \u003e message.bin\n\nThen examine (cf. [official docs](https://developers.google.com/protocol-buffers/docs/encoding#simple)):\n\n    $ hd /tmp/msg.bin\n    00000000  08 96 01                                          |...|\n    00000003\n\nAnother example: `message Test2 { string b = 2; }` with `b = \"testing\"`:\n\n    pw 2 string testing\n\nMore complex examples (also from [here](https://developers.google.com/protocol-buffers/docs/encoding#embedded)) can be composed using standard UNIX tools\n\n    pw int 150 | pw 3 bytes\n\nand\n\n    (pw fixed64 10 \u0026\u0026 pw 2 bool true) | pw 4 bytes\n\n## GRPC client\n\nThis tool also requires the `grpcio` Python package (`pip install grpcio`)\n\n    pw-grpc-client (-is) (-os) (--tag 1) host:port/path\n\nConsider the following example:\n\n```protobuf\nsyntax = \"proto3\";\n\nmessage RequestThing {\n    string query = 1;\n}\n\nmessage ResponseItem {\n    int32 foo = 1;\n    // ...\n}\n\nservice MyService {\n    rpc UnaryMethod(RequestThing) returns (ResponseItem) {}\n    rpc ServerStream(RequestThing) returns (stream ResponseItem) {}\n    rpc ClientStream(stream RequestThing) returns (ResponseItem) {}\n    rpc BidirectionalStream(stream RequestThing) returns (stream ResponseItem) {}\n}\n\n// helper collections\nmessage RequestCollection {\n    repeated RequestThing things = 1;\n}\n\nmessage ResponseCollection {\n    repeated ResponseItem items = 1;\n}\n```\n\nAn **`UnaryMethod`** call using a `RequestThing` with `query = \"hello\"` can be sent to a server running at `localhost:8000` as follows:\n\n    pw string \"hello\" | \\\n        pw-grpc-client localhost:8000/MyService/UnaryMethod \\\n        \u003e response_item.bin\n\nwhich saves the obtained `ResponseItem` protobuf the file `response_item.bin`.\n\nIt is also possible to convert **`ServerStream`** responses to protobuf `ResponseCollection`s using the `-os`/`--stream_response` flag:\n\n    pw string \"hello\" | \\\n        pw-grpc-client localhost:8000/MyService/ServerStream -os \\\n        \u003e response_collection.bin\n\nSimilarly, **`ClientStream`** can be constructed from `RequestCollection`s with `-is`/`--stream_request`:\n\n    pw string \"singleton item\" | pw 1 bytes | \\\n        pw-grpc-client localhost:8000/MyService/ClientStream -is \\\n        \u003e response_item.bin\n\nThe flags `-is` and `-os` can be used simultaneously for **`BidirectionalStream`**\n\n    ((pw string \"first\" | pw bytes) \u0026\u0026 (pw string \"second\" | pw bytes)) | \\\n        pw-grpc-client localhost:8000/MyService/BidirectionalStream -is -os \\\n        \u003e response_collection.bin\n\nIn all `-os`-cases, there is also a `--tag` flag that can be used to change the field number in the response protobuf collection. For example `message ResponseCollection { repeated ResponseItem items = 2; }` would require:\n\n    pw string \"hello\" | \\\n        pw-grpc-client localhost:8000/MyService/ServerStream -os --tag 2 \\\n        \u003e response_collection.bin\n\n## GRPC frames for low-level communication\n\nThis tool does not need any GRPC or protbuf packages, but can be combined with a HTTP/2 client like `nghttp` to make GRPC calls.\nUsage:\n\n    pw-grpc-frame [wrap|unwrap] (--stream) (--tag 1)\n\nWrap into a GRPC frame and unwrap the response to normal protobuf:\n\n    pw 1 string \"my query\" | pw-grpc-frame wrap \u003e request.bin\n    nghttp -H \":method: POST\" -H \"Content-Type: application/grpc\" -H \"TE: trailers\" \\\n        --data=request.bin \\\n        http://localhost:8000/MyService/UnaryMethod \\\n        | pw-grpc-frame unwrap \u003e /tmp/output.bin\n\nThe option `--stream` can be used with both wrap and unwrap to convert protobuf collections to GRPC streams like in the other GRPC client example. The `--tag` option can be used to change the field number in the \"unwrapped\" protobuf collection.\n\nNotice that older versions of `nghttp` (like 0.6.4 in Debian Jessie) [cannot read STDIN](https://github.com/nghttp2/nghttp2/issues/133) with `-d -`.\n\n## Development\n\n 1. Create virtualenv\n    * Python 2: `virtualenv venvs/python2`\n    * Python 3: `python3 -m venv venvs/python3`\n 1. Activate virtualenv: `source venvs/pythonNNN/bin/activate`\n 1. Install locally `pip install -e .[dev]`\n 1. `./run-tests.sh`\n 1. `deactivate` virtualenv\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foseiskar%2Fprotowire","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foseiskar%2Fprotowire","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foseiskar%2Fprotowire/lists"}