generate_pb.sh 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. #!/usr/bin/env bash
  2. # Regenerate the vendored Python protobuf + ConnectRPC bindings under
  3. # src/chattolib/_pb.
  4. #
  5. # Fetches the required .proto sources into proto/ (from chattocorp/chatto's
  6. # main branch and bufbuild/protovalidate) and runs protoc with both the
  7. # built-in Python code generator and the connect-python plugin.
  8. #
  9. # Requirements:
  10. # - protoc on PATH
  11. # - protoc-gen-connect-python on PATH (install via
  12. # `pip install protoc-gen-connect-python`, which chattolib pins under
  13. # the `[realtime]` extra)
  14. # - curl on PATH
  15. #
  16. # Run from the repo root: ./scripts/generate_pb.sh
  17. set -euo pipefail
  18. if ! command -v protoc >/dev/null; then
  19. echo "protoc not found on PATH" >&2
  20. exit 1
  21. fi
  22. repo_root=$(cd "$(dirname "$0")/.." && pwd)
  23. cd "$repo_root"
  24. mkdir -p proto/chatto/{api,admin,auth,discovery,realtime}/v1 proto/buf/validate
  25. chatto_base="https://raw.githubusercontent.com/chattocorp/chatto/main/proto/chatto"
  26. fetch() {
  27. local rel=$1
  28. curl -sfL "$chatto_base/${rel#chatto/}" -o "proto/$rel"
  29. echo " $rel"
  30. }
  31. echo "Fetching proto sources ..."
  32. # chatto.api.v1
  33. for f in \
  34. account.proto attachments.proto asset_uploads.proto common.proto \
  35. external_identities.proto link_previews.proto member_directory.proto \
  36. messages.proto message_types.proto notification_preferences.proto \
  37. notifications.proto pagination.proto permissions.proto presence.proto \
  38. push_notifications.proto reactions.proto read_state.proto \
  39. room_directory.proto rooms.proto room_timeline.proto roles.proto \
  40. server.proto server_state.proto threads.proto users.proto \
  41. user_status.proto viewer.proto voice_calls.proto
  42. do
  43. fetch "chatto/api/v1/$f"
  44. done
  45. # chatto.admin.v1
  46. for f in \
  47. diagnostics.proto event_log.proto members.proto permissions.proto \
  48. roles.proto room_layout.proto server.proto
  49. do
  50. fetch "chatto/admin/v1/$f"
  51. done
  52. # chatto.auth.v1
  53. fetch chatto/auth/v1/external_identity_auth.proto
  54. # chatto.discovery.v1
  55. fetch chatto/discovery/v1/server.proto
  56. # chatto.realtime.v1
  57. fetch chatto/realtime/v1/realtime.proto
  58. # buf.validate — sourced from bufbuild/protovalidate
  59. curl -sfL \
  60. "https://raw.githubusercontent.com/bufbuild/protovalidate/main/proto/protovalidate/buf/validate/validate.proto" \
  61. -o proto/buf/validate/validate.proto
  62. echo " buf/validate/validate.proto"
  63. echo "Regenerating Python bindings ..."
  64. rm -rf src/chattolib/_pb/chatto src/chattolib/_pb/buf
  65. mkdir -p src/chattolib/_pb
  66. # Collect every input .proto so protoc's plugins visit each service.
  67. mapfile -t proto_files < <(find proto -type f -name '*.proto' | sort)
  68. protoc --proto_path=proto \
  69. --python_out=src/chattolib/_pb \
  70. "${proto_files[@]}"
  71. # Only run the connect-python plugin when it is available. The realtime
  72. # WebSocket path only needs the pb2 files; every request/response service is
  73. # strongly typed via the connect stubs.
  74. if command -v protoc-gen-connect-python >/dev/null; then
  75. protoc --proto_path=proto \
  76. --connect-python_out=src/chattolib/_pb \
  77. "${proto_files[@]}"
  78. else
  79. echo "protoc-gen-connect-python not on PATH; skipped connect stubs" >&2
  80. fi
  81. # Add __init__.py at every level so the generated modules form a package.
  82. find src/chattolib/_pb \( -path '*/chatto*' -o -path '*/buf*' \) -type d \
  83. | while read -r dir; do touch "$dir/__init__.py"; done
  84. echo "Done."