protoc-gen-openapiv2 Python Wrapper

0.0.1 · active · verified Sat Apr 11

This Python package provides a convenient wrapper to install the `protoc-gen-openapiv2` binary. The binary generates OpenAPI v2 (Swagger) definitions directly from Protocol Buffer service definitions, making it a critical component for gRPC Gateway projects to expose gRPC services as RESTful APIs. It is currently at version 0.0.1, with development closely tied to the upstream Go project.

Warnings

Install

Quickstart

This quickstart demonstrates how to use the `protoc-gen-openapiv2` plugin via a Python script. It creates a dummy `.proto` file, then executes the `protoc` command to generate an OpenAPI v2 specification. This highlights that the package primarily provides a command-line tool, not Python symbols for direct import. Ensure `protoc` is installed and `protoc-gen-openapiv2` is in your system's PATH.

import subprocess
import os
import sys

# --- Prerequisites Check --- 
# This library's core function is a 'protoc' plugin, so 'protoc' and the plugin
# binary must be available in your system's PATH.

def check_command(cmd_name):
    return subprocess.run(["which", cmd_name], capture_output=True).returncode == 0

if not check_command("protoc"):
    print("Error: 'protoc' (Protocol Buffer compiler) not found in PATH.", file=sys.stderr)
    print("Please install protoc. E.g., on Debian/Ubuntu: 'sudo apt install protobuf-compiler'", file=sys.stderr)
    sys.exit(1)

if not check_command("protoc-gen-openapiv2"):
    print("Error: 'protoc-gen-openapiv2' not found in PATH.", file=sys.stderr)
    print("This Python package installs the binary, but you may need to add its install location (e.g., ~/.local/bin) to your PATH.", file=sys.stderr)
    sys.exit(1)

# --- 1. Create a dummy .proto file for demonstration ---
proto_file = "example.proto"
output_dir = "./openapi_output"
swagger_output_file = os.path.join(output_dir, "example.swagger.json")

proto_content = """
syntax = "proto3";
package example;
import "google/api/annotations.proto"; // Essential for gRPC Gateway HTTP annotations

service MyService {
  rpc MyMethod (MyRequest) returns (MyResponse) {
    option (google.api.http) = {
      get: "/v1/example/{query}"
    };
  }
}
message MyRequest {
  string query = 1;
}
message MyResponse {
  string result = 1;
}
"""
with open(proto_file, "w") as f:
    f.write(proto_content)

os.makedirs(output_dir, exist_ok=True)

# --- 2. Run protoc with the openapiv2 plugin ---
# The 'google/api/annotations.proto' needs to be discoverable by protoc.
# It's typically found in your protoc installation or the grpc-gateway repo.
# If not, you might need to add: -I/path/to/grpc-gateway/third_party/googleapis
protoc_command = [
    "protoc",
    "-I.", # Look for proto files in the current directory
    f"--openapiv2_out={output_dir}", # Output directory for OpenAPI spec
    "--openapiv2_opt=logtostderr=true", # Optional: log to stderr for debugging
    proto_file
]

print(f"Executing command: {' '.join(protoc_command)}\n")

try:
    result = subprocess.run(protoc_command, check=True, capture_output=True, text=True)
    print("STDOUT:\n", result.stdout)
    if result.stderr:
        print("STDERR:\n", result.stderr) # Often contains warnings or logs from the plugin
    print(f"\nSuccessfully generated OpenAPI v2 spec at: {swagger_output_file}")
except subprocess.CalledProcessError as e:
    print(f"Error generating OpenAPI spec: {e}", file=sys.stderr)
    print(f"Command: {' '.join(e.cmd)}", file=sys.stderr)
    print(f"STDOUT:\n{e.stdout}", file=sys.stderr)
    print(f"STDERR:\n{e.stderr}", file=sys.stderr)
    sys.exit(1)
except FileNotFoundError as e:
    print(f"Error: Command not found. {e}", file=sys.stderr)
    sys.exit(1)
finally:
    # --- Clean up --- 
    if os.path.exists(proto_file):
        os.remove(proto_file)
    print(f"\nCleaned up temporary '{proto_file}'. The output spec remains in '{output_dir}'.")

view raw JSON →