Skip to content

Add Python protobuf bindings pipeline and PyPI release workflow - #291

Merged
pfi79 merged 6 commits into
hyperledger:mainfrom
kmilodenisglez:feat/python-bindings-pipeline
Sep 14, 2026
Merged

pfi79 merged 6 commits into
hyperledger:mainfrom
kmilodenisglez:feat/python-bindings-pipeline

Conversation

@kmilodenisglez

Copy link
Copy Markdown
Contributor

Summary
This pull request adds first-class Python bindings generation, packaging, and release automation to fabric-protos.

Motivation
I am currently implementing the Python Fabric Gateway client and preparing its contribution for review. To validate and submit that gateway PR properly, we need official Python protobuf and gRPC bindings published from fabric-protos, with a repeatable generation process and a release path to PyPI.

What is included

  1. Makefile support for Python bindings generation with a pinned grpcio-tools version and a dedicated pythonbindings target.
  2. New generator script for Python protobuf and gRPC sources.
  3. Import-rewrite helper to ensure generated modules use the fabric_protos package namespace, plus package markers and py.typed.
  4. Python package scaffold under bindings/python with pyproject metadata and package README.
  5. CI version parity check against BINDING_VERSION for the Python package version.
  6. New Python bindings workflow that:
  • builds bindings and distributions on pull requests and main branch pushes,
  • uploads build artifacts for non-release runs,
  • publishes to PyPI only on release-tag conditions.

Validation performed

  1. make pythonbindings
  2. python -m build
  3. python -m twine check dist/*
  4. actionlint for the workflow files

All checks above pass.

Impact

  1. No behavior change for existing Go, Java, or Node bindings.
  2. Establishes the required Python artifact pipeline so downstream Python SDK work can be validated against an official package flow.

Follow-up
After this lands, the Fabric Gateway Python PR can consume and validate against these published Python protobuf bindings.

Signed-off-by: kmilo <kmilo.denis.glez@yandex.com>
Signed-off-by: kmilo <kmilo.denis.glez@yandex.com>
@kmilodenisglez
kmilodenisglez requested a review from a team as a code owner September 11, 2026 15:51
@jt-nti

jt-nti commented Sep 11, 2026

Copy link
Copy Markdown
Member

Hi @kmilodenisglez, thanks for the PR!

It's great to hear you're working on the Python Fabric Gateway client, and adding the Python fabric proto bindings here is nice. I noticed you added a python specific build script instead of using buf in the same way as the other languages. Was that due to grpc/grpc#26125 or was it for a different reason?

Thanks again, James

@kmilodenisglez

kmilodenisglez commented Sep 11, 2026 •

Copy link
Copy Markdown
Contributor Author

Hi @kmilodenisglez, thanks for the PR!

It's great to hear you're working on the Python Fabric Gateway client, and adding the Python fabric proto bindings here is nice. I noticed you added a python specific build script instead of using buf in the same way as the other languages. Was that due to grpc/grpc#26125 or was it for a different reason?

Thanks again, James

Hi @jt-nti, thanks for checking this.

Short answer: partly related, but the main reason was packaging and import stability for a publishable Python artifact.

Using buf alone is fine for proto generation, but for Python we still needed a deterministic post-generation step to make the generated modules work correctly inside the fabric_protos package namespace (including package markers and import rewriting). The import behavior in grpc/protobuf Python generation is in the same area as grpc/grpc#26125, so that issue was a factor in the decision, but not the only reason.

I used the dedicated script so the Python wheel/sdist are reproducible and import-safe for downstream use in the Python Fabric Gateway client PR.

If maintainers prefer, I can also switch this to a buf-driven entry point plus the same post-processing step.

@jt-nti

jt-nti commented Sep 13, 2026

Copy link
Copy Markdown
Member

Hi @kmilodenisglez, thanks for the reply. It sounds like the post-processing step could work with buf generation in the future. If the maintainers are happy with everything else (I'm not a Python expert!), I don't think switching to buf now should be a blocker given the issue with the protoc plugin. It would be good to update the README.md and RELEASING.md files to mention the new binding though, with a comment about not using buf, before merging.

Signed-off-by: kmilo <kmilo.denis.glez@yandex.com>
Signed-off-by: kmilo <kmilo.denis.glez@yandex.com>
@kmilodenisglez

Copy link
Copy Markdown
Contributor Author

Hi @kmilodenisglez, thanks for the reply. It sounds like the post-processing step could work with buf generation in the future. If the maintainers are happy with everything else (I'm not a Python expert!), I don't think switching to buf now should be a blocker given the issue with the protoc plugin. It would be good to update the README.md and RELEASING.md files to mention the new binding though, with a comment about not using buf, before merging.

Hi @jt-nti, thanks for the feedback. I have updated both README.md and RELEASING.md to include the new Python binding, the Python package release artifact, and a note that Python generation currently uses grpc_tools.protoc plus post-processing (not direct buf generate yet). I also added the Python pyproject version file to the release versioning checklist.

@jt-nti

jt-nti commented Sep 14, 2026

Copy link
Copy Markdown
Member

Thanks @kmilodenisglez, that looks great.

@pfi79, could you have a look when you get a chance please?

@pfi79 pfi79 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unclear questions

Comment thread bindings/python/src/fabric_protos/__init__.py
Comment thread bindings/python/src/fabric_protos/py.typed
Comment thread scripts/fix_python_imports.py Outdated
Signed-off-by: kmilo <kmilo.denis.glez@yandex.com>
Signed-off-by: kmilo <kmilo.denis.glez@yandex.com>
@pfi79
pfi79 merged commit 8a4c79c into hyperledger:main Sep 14, 2026
24 checks passed
@pfi79

pfi79 commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

@kmilodenisglez where can I see the result?

@kmilodenisglez

kmilodenisglez commented Sep 14, 2026 •

Copy link
Copy Markdown
Contributor Author

where can I see the result?

@pfi79 , in the specific job (Build Python bindings). To view downloadable artifacts:

  1. Click on Summary (the first option in the left side menu, above All jobs).
  2. Scroll to the bottom of the summary page. The Artifacts block will appear there.

@kmilodenisglez

Copy link
Copy Markdown
Contributor Author

@pfi79 Just a quick heads-up regarding the CI run:

The build completed successfully, but the Publish to PyPI step was skipped. (PyPI is the official public registry for Python packages—similar to npm for Node.js or Maven for Java—where users download libraries via pip).

I think this might have been skipped because this run was triggered from a PR/branch without a release tag—could that be the reason? If so, will it automatically publish to PyPI once this gets merged into main and a release tag (e.g., v1.0.0) is pushed?

@pfi79

pfi79 commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

@pfi79 Just a quick heads-up regarding the CI run:

The build completed successfully, but the Publish to PyPI step was skipped. (PyPI is the official public registry for Python packages—similar to npm for Node.js or Maven for Java—where users download libraries via pip).

I think this might have been skipped because this run was triggered from a PR/branch without a release tag—could that be the reason? If so, will it automatically publish to PyPI once this gets merged into main and a release tag (e.g., v1.0.0) is pushed?

Look, every successful pr poured into main is published. So made for go and for node.
Can I do it for python as well?

@kmilodenisglez

Copy link
Copy Markdown
Contributor Author

@pfi79 Just a quick heads-up regarding the CI run:
The build completed successfully, but the Publish to PyPI step was skipped. (PyPI is the official public registry for Python packages—similar to npm for Node.js or Maven for Java—where users download libraries via pip).
I think this might have been skipped because this run was triggered from a PR/branch without a release tag—could that be the reason? If so, will it automatically publish to PyPI once this gets merged into main and a release tag (e.g., v1.0.0) is pushed?

Look, every successful pr poured into main is published. So made for go and for node. Can I do it for python as well?

Yes @pfi79 . I checked the Python workflow together with ci-checks.yml and compared it with the Node.js workflow.

The existing Python workflow already has the development-version handling needed for PyPI. For non-release builds it converts, for example, 0.3.7 into a unique PEP 440 version such as 0.3.7.dev<github_run_id><github_run_attempt>.

Now non-release Python distributions are currently uploaded as GitHub Actions artifacts instead of being published to PyPI.

So I can align it with the Node.js behavior by publishing on every non-PR push, while keeping the existing release detection:

  • PR → will continue to validate the build and store artifacts without publishing to PyPI.
  • main → publish the unique 0.3.7.dev... package to PyPI (matching the Node workflow publishing to next-unstable).
  • Release tags (v*) publish the clean release version (0.3.7) to PyPI.

No changes to ci-checks.yml should be necessary.

I'll push this update to the PR shortly!

@kmilodenisglez

Copy link
Copy Markdown
Contributor Author

@pfi79 this is the new PR

@kmilodenisglez
kmilodenisglez deleted the feat/python-bindings-pipeline branch September 15, 2026 17:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants