xref: /aosp_15_r20/external/grpc-grpc/summerofcode/2018/naresh.md (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1*cc02d7e2SAndroid Build Coastguard Worker# Project overview
2*cc02d7e2SAndroid Build Coastguard Worker
3*cc02d7e2SAndroid Build Coastguard Worker## Title
4*cc02d7e2SAndroid Build Coastguard Worker
5*cc02d7e2SAndroid Build Coastguard WorkerEnable Building of gRPC Python with Bazel
6*cc02d7e2SAndroid Build Coastguard Worker
7*cc02d7e2SAndroid Build Coastguard Worker## Overview
8*cc02d7e2SAndroid Build Coastguard Worker
9*cc02d7e2SAndroid Build Coastguard WorkergRPC Python currently has a constellation of scripts written to build the
10*cc02d7e2SAndroid Build Coastguard Workerproject, but it has a lot of limitations in terms of speed and maintainability.
11*cc02d7e2SAndroid Build Coastguard Worker[Bazel](https://bazel.build/) is the open-sourced variant of Google's internal
12*cc02d7e2SAndroid Build Coastguard Workersystem, Blaze, which is an ideal replacement for building such projects in a
13*cc02d7e2SAndroid Build Coastguard Workerfast and declarative fashion. But Bazel in itself is still in active
14*cc02d7e2SAndroid Build Coastguard Workerdevelopment, especially in terms of Python (amongst a few other languages).
15*cc02d7e2SAndroid Build Coastguard Worker
16*cc02d7e2SAndroid Build Coastguard WorkerThe project aimed to fill this gap and build gRPC Python with Bazel.
17*cc02d7e2SAndroid Build Coastguard Worker
18*cc02d7e2SAndroid Build Coastguard Worker[Project page](https://summerofcode.withgoogle.com/projects/#6482576244473856)
19*cc02d7e2SAndroid Build Coastguard Worker
20*cc02d7e2SAndroid Build Coastguard Worker[Link to proposal](https://storage.googleapis.com/summerofcode-prod.appspot.com/gsoc/core_project/doc/5316764725411840_1522049732_Naresh_Ramesh_-_GSoC_proposal.pdf)
21*cc02d7e2SAndroid Build Coastguard Worker
22*cc02d7e2SAndroid Build Coastguard Worker## Thoughts and challenges
23*cc02d7e2SAndroid Build Coastguard Worker
24*cc02d7e2SAndroid Build Coastguard Worker### State of Bazel for Python
25*cc02d7e2SAndroid Build Coastguard Worker
26*cc02d7e2SAndroid Build Coastguard WorkerAlthough previously speculated, the project didn't require any contributions
27*cc02d7e2SAndroid Build Coastguard Workerdirectly to [bazelbuild/bazel](https://github.com/bazelbuild/bazel). The Bazel
28*cc02d7e2SAndroid Build Coastguard Workerrules for Python are currently being separated out into their own repo at
29*cc02d7e2SAndroid Build Coastguard Worker[bazelbuild/rules_python](https://github.com/bazelbuild/rules_python/).
30*cc02d7e2SAndroid Build Coastguard Worker
31*cc02d7e2SAndroid Build Coastguard WorkerBazel is [still very much in active development for
32*cc02d7e2SAndroid Build Coastguard WorkerPython](https://groups.google.com/forum/#!topic/bazel-sig-python/iQjV9sfSufw)
33*cc02d7e2SAndroid Build Coastguard Workerthough. There's still challenges when it comes to building for Python 2 vs 3.
34*cc02d7e2SAndroid Build Coastguard WorkerUsing pip packages is still in experimental. Bazel Python support is currently
35*cc02d7e2SAndroid Build Coastguard Workerdistributed across these two repositories and is yet to begin migration to one
36*cc02d7e2SAndroid Build Coastguard Workerplace (which will be
37*cc02d7e2SAndroid Build Coastguard Worker[bazelbuild/rules_python](https://github.com/bazelbuild/rules_python/)).
38*cc02d7e2SAndroid Build Coastguard Worker
39*cc02d7e2SAndroid Build Coastguard WorkerBazel's roadmap for Python is publicly available [here as a Google
40*cc02d7e2SAndroid Build Coastguard Workerdoc](https://docs.google.com/document/d/1A6J3j3y1SQ0HliS86_mZBnB5UeBe7vExWL2Ryd_EONI/edit).
41*cc02d7e2SAndroid Build Coastguard Worker
42*cc02d7e2SAndroid Build Coastguard Worker### Cross collaboration between projects
43*cc02d7e2SAndroid Build Coastguard Worker
44*cc02d7e2SAndroid Build Coastguard WorkerCross contribution surprisingly came up because of building protobuf sources
45*cc02d7e2SAndroid Build Coastguard Workerfor Python, which is still not natively supported by Bazel. An existing
46*cc02d7e2SAndroid Build Coastguard Workerrepository, [pubref/rules_protobuf](https://github.com/pubref/rules_protobuf),
47*cc02d7e2SAndroid Build Coastguard Workerwhich was maintained by an independent maintainer (i.e. not a part of Bazel)
48*cc02d7e2SAndroid Build Coastguard Workerhelped solve this problem, but had [one major blocking
49*cc02d7e2SAndroid Build Coastguard Workerissue](https://github.com/pubref/rules_protobuf/issues/233) and could not be
50*cc02d7e2SAndroid Build Coastguard Workerresolved at the source. But [a solution to the
51*cc02d7e2SAndroid Build Coastguard Workerissue](https://github.com/pubref/rules_protobuf/pull/196) was proposed by user
52*cc02d7e2SAndroid Build Coastguard Workerdududko, which was not merged because of failing golang tests but worked well
53*cc02d7e2SAndroid Build Coastguard Workerfor Python. Hence, a fork of this repo was made and is to be used with gRPC
54*cc02d7e2SAndroid Build Coastguard Workeruntil the solution can be merged back at the source.
55*cc02d7e2SAndroid Build Coastguard Worker
56*cc02d7e2SAndroid Build Coastguard Worker### Building Cython code
57*cc02d7e2SAndroid Build Coastguard Worker
58*cc02d7e2SAndroid Build Coastguard WorkerBuilding Cython code is still not supported by Bazel, but the team at
59*cc02d7e2SAndroid Build Coastguard Worker[cython/cython](https://github.com/cython/cython) have added support for Bazel
60*cc02d7e2SAndroid Build Coastguard Workeron their side. The way it works is by including Cython as a third-party Bazel
61*cc02d7e2SAndroid Build Coastguard Workerdependency and using custom Bazel rules for building our Cython code using the
62*cc02d7e2SAndroid Build Coastguard Workerbinary within the dependency.
63*cc02d7e2SAndroid Build Coastguard Worker
64*cc02d7e2SAndroid Build Coastguard Worker### Packaging Python code using Bazel
65*cc02d7e2SAndroid Build Coastguard Worker
66*cc02d7e2SAndroid Build Coastguard Workerpip and PyPI still remain the de-facto standard for distributing Python
67*cc02d7e2SAndroid Build Coastguard Workerpackages. Although Bazel is pretty versatile and is amazing for it's
68*cc02d7e2SAndroid Build Coastguard Workerreproducible and incremental build capabilities, these can only be still used
69*cc02d7e2SAndroid Build Coastguard Workerby the contributors and developers for building and testing the gRPC code. But
70*cc02d7e2SAndroid Build Coastguard Workerthere's no way yet to build Python packages for distribution.
71*cc02d7e2SAndroid Build Coastguard Worker
72*cc02d7e2SAndroid Build Coastguard Worker### Building gRPC Python with Bazel on Kokoro (internal CI)
73*cc02d7e2SAndroid Build Coastguard Worker
74*cc02d7e2SAndroid Build Coastguard WorkerIntegration with the internal CI was one of the areas that highlighted how
75*cc02d7e2SAndroid Build Coastguard Workersimple Bazel can be to use. gRPC was already using a dockerized Bazel setup to
76*cc02d7e2SAndroid Build Coastguard Workerbuild some of it's core code (but not as the primary build setup). Adding a new
77*cc02d7e2SAndroid Build Coastguard Workerjob on the internal CI ended up being as simple as creating a new shell script
78*cc02d7e2SAndroid Build Coastguard Workerto install the required dependencies (which were python-dev and Bazel) and a
79*cc02d7e2SAndroid Build Coastguard Workernew configuration file which pointed to the subdirectiory (src/python) under
80*cc02d7e2SAndroid Build Coastguard Workerwhich to look for targets and run the tests accordingly.
81*cc02d7e2SAndroid Build Coastguard Worker
82*cc02d7e2SAndroid Build Coastguard Worker### Handling imports in Python code
83*cc02d7e2SAndroid Build Coastguard Worker
84*cc02d7e2SAndroid Build Coastguard WorkerWhen writing Python packages, imports in nested modules are typically made
85*cc02d7e2SAndroid Build Coastguard Workerrelative to the package root. But because of the way Bazel works, these paths
86*cc02d7e2SAndroid Build Coastguard Workerwouldn't make sense from the Workspace root. So, the folks at Bazel have added
87*cc02d7e2SAndroid Build Coastguard Workera nifty `imports` parameter to all the Python rules which lets us specify for
88*cc02d7e2SAndroid Build Coastguard Workereach target, which path to consider as the root. This parameter allows for
89*cc02d7e2SAndroid Build Coastguard Workerrelative paths like `imports = ["../",]`.
90*cc02d7e2SAndroid Build Coastguard Worker
91*cc02d7e2SAndroid Build Coastguard Worker### Fetching Python headers for Cython code to use
92*cc02d7e2SAndroid Build Coastguard Worker
93*cc02d7e2SAndroid Build Coastguard WorkerCython code makes use of `Python.h`, which pulls in the Python API for C
94*cc02d7e2SAndroid Build Coastguard Workerextension modules to use, but it's location depending on the Python version and
95*cc02d7e2SAndroid Build Coastguard Workeroperating system the code is building on. To make this easier, the folks at
96*cc02d7e2SAndroid Build Coastguard WorkerTensorflow wrote [repository rules for Python
97*cc02d7e2SAndroid Build Coastguard Workerautoconfiguration](https://github.com/tensorflow/tensorflow/tree/e447ae4759317156d31a9421290716f0ffbffcd8/third_party/py).
98*cc02d7e2SAndroid Build Coastguard WorkerThis has been [adapted with some some
99*cc02d7e2SAndroid Build Coastguard Workermodifications](https://github.com/grpc/grpc/pull/15992) for use in gRPC Python
100*cc02d7e2SAndroid Build Coastguard Workeras well.
101*cc02d7e2SAndroid Build Coastguard Worker
102*cc02d7e2SAndroid Build Coastguard Worker## How to use
103*cc02d7e2SAndroid Build Coastguard Worker
104*cc02d7e2SAndroid Build Coastguard WorkerAll the Bazel tests for gRPC Python can be run using a single command:
105*cc02d7e2SAndroid Build Coastguard Worker
106*cc02d7e2SAndroid Build Coastguard Worker```bash
107*cc02d7e2SAndroid Build Coastguard Workerbazel test --spawn_strategy=standalone --genrule_strategy=standalone //src/python/...
108*cc02d7e2SAndroid Build Coastguard Worker```
109*cc02d7e2SAndroid Build Coastguard Worker
110*cc02d7e2SAndroid Build Coastguard WorkerIf any specific test is to be run, like say `LoggingPoolTest` (which is present
111*cc02d7e2SAndroid Build Coastguard Workerin
112*cc02d7e2SAndroid Build Coastguard Worker`src/python/grpcio_tests/tests/unit/framework/foundation/_logging_pool_test.py`),
113*cc02d7e2SAndroid Build Coastguard Workerthe command to run would be:
114*cc02d7e2SAndroid Build Coastguard Worker
115*cc02d7e2SAndroid Build Coastguard Worker```bash
116*cc02d7e2SAndroid Build Coastguard Workerbazel test --spawn_strategy=standalone --genrule_strategy=standalone //src/python/grpcio_tests/tests/unit/framework/foundation:logging_pool_test
117*cc02d7e2SAndroid Build Coastguard Worker```
118*cc02d7e2SAndroid Build Coastguard Worker
119*cc02d7e2SAndroid Build Coastguard Workerwhere, `logging_pool_test` is the name of the Bazel target for this test.
120*cc02d7e2SAndroid Build Coastguard Worker
121*cc02d7e2SAndroid Build Coastguard WorkerSimilarly, to run a particular method, use:
122*cc02d7e2SAndroid Build Coastguard Worker
123*cc02d7e2SAndroid Build Coastguard Worker```bash
124*cc02d7e2SAndroid Build Coastguard Workerbazel test --spawn_strategy=standalone --genrule_strategy=standalone //src/python/grpcio_tests/tests/unit/_rpc_test --test_arg=RPCTest.testUnrecognizedMethod
125*cc02d7e2SAndroid Build Coastguard Worker```
126*cc02d7e2SAndroid Build Coastguard Worker
127*cc02d7e2SAndroid Build Coastguard Worker## Useful Bazel flags
128*cc02d7e2SAndroid Build Coastguard Worker
129*cc02d7e2SAndroid Build Coastguard Worker- Use `bazel build` with a `-s` flag to see the logs being printed out to
130*cc02d7e2SAndroid Build Coastguard Worker    standard output while building.
131*cc02d7e2SAndroid Build Coastguard Worker- Similarly, use `bazel test` with a `--test_output=streamed` to see the
132*cc02d7e2SAndroid Build Coastguard Worker    test logs while testing. Something to know while using this flag is that all
133*cc02d7e2SAndroid Build Coastguard Worker    tests will be run locally, without sharding, one at a time.
134*cc02d7e2SAndroid Build Coastguard Worker
135*cc02d7e2SAndroid Build Coastguard Worker## Contributions
136*cc02d7e2SAndroid Build Coastguard Worker
137*cc02d7e2SAndroid Build Coastguard Worker### Related to the project
138*cc02d7e2SAndroid Build Coastguard Worker
139*cc02d7e2SAndroid Build Coastguard Worker- [435c6f8](https://github.com/grpc/grpc/commit/435c6f8d1e53783ec049b3482445813afd8bc514)
140*cc02d7e2SAndroid Build Coastguard Worker    Update grpc_gevent cython files to include .pxi
141*cc02d7e2SAndroid Build Coastguard Worker- [74426fd](https://github.com/grpc/grpc/commit/74426fd2164c51d6754732ebe372133c19ba718c)
142*cc02d7e2SAndroid Build Coastguard Worker    Add gevent_util.h to grpc_base_c Bazel target
143*cc02d7e2SAndroid Build Coastguard Worker- [b6518af](https://github.com/grpc/grpc/commit/b6518afdd610f0115b42aee1ffc71520c6b0d6b1)
144*cc02d7e2SAndroid Build Coastguard Worker    Upgrade Bazel to 0.15.0
145*cc02d7e2SAndroid Build Coastguard Worker- [ebcf04d](https://github.com/grpc/grpc/commit/ebcf04d075333c42979536c5dd2091d363f67e5a)
146*cc02d7e2SAndroid Build Coastguard Worker    Kokoro setup for building gRPC Python with Bazel
147*cc02d7e2SAndroid Build Coastguard Worker- [3af1aaa](https://github.com/grpc/grpc/commit/3af1aaadabf49bc6274711a11f81627c0f351a9a)
148*cc02d7e2SAndroid Build Coastguard Worker    Basic setup to build gRPC Python with Bazel
149*cc02d7e2SAndroid Build Coastguard Worker- [11f199e](https://github.com/grpc/grpc/commit/11f199e34dc416a2bd8b56391b242a867bedade4)
150*cc02d7e2SAndroid Build Coastguard Worker    Workspace changes to build gRPC Python with Bazel
151*cc02d7e2SAndroid Build Coastguard Worker- [848fd9d](https://github.com/grpc/grpc/commit/848fd9d75f6df10f00e8328ff052c0237b3002ab)
152*cc02d7e2SAndroid Build Coastguard Worker    Minimal Bazel BUILD files for grpcio Python
153*cc02d7e2SAndroid Build Coastguard Worker
154*cc02d7e2SAndroid Build Coastguard Worker### Other contibutions
155*cc02d7e2SAndroid Build Coastguard Worker
156*cc02d7e2SAndroid Build Coastguard Worker- [89ce16b](https://github.com/grpc/grpc/commit/89ce16b6daaad4caeb1c9ba670c6c4b62ea1a93c)
157*cc02d7e2SAndroid Build Coastguard Worker    Update Dockerfiles for python artifacts to use latest git version
158*cc02d7e2SAndroid Build Coastguard Worker- [32f7c48](https://github.com/grpc/grpc/commit/32f7c48dad71cac7af652bf994ab1dde3ddb0607)
159*cc02d7e2SAndroid Build Coastguard Worker    Revert removals from python artifact dockerfiles
160*cc02d7e2SAndroid Build Coastguard Worker- [712eb9f](https://github.com/grpc/grpc/commit/712eb9ff91cde66af94e8381ec01ad512ed6d03c)
161*cc02d7e2SAndroid Build Coastguard Worker    Make logging after success in jobset more apparent
162*cc02d7e2SAndroid Build Coastguard Worker- [c6e4372](https://github.com/grpc/grpc/commit/c6e4372f8a93bb0eb996b5f202465785422290f2)
163*cc02d7e2SAndroid Build Coastguard Worker    Create README for gRPC Python reflection package
164*cc02d7e2SAndroid Build Coastguard Worker- [2e113ca](https://github.com/grpc/grpc/commit/2e113ca6b2cc31aa8a9687d40ee1bd759381654f)
165*cc02d7e2SAndroid Build Coastguard Worker    Update logging in Python to use module-level logger
166*cc02d7e2SAndroid Build Coastguard Worker
167*cc02d7e2SAndroid Build Coastguard Worker### Pending PRs
168*cc02d7e2SAndroid Build Coastguard Worker
169*cc02d7e2SAndroid Build Coastguard Worker- BUILD files for all tests in
170*cc02d7e2SAndroid Build Coastguard Worker    [tests.json](https://github.com/ghostwriternr/grpc/blob/70c8a58b2918a5369905e5a203d7ce7897b6207e/src/python/grpcio_tests/tests/tests.json).
171*cc02d7e2SAndroid Build Coastguard Worker- BUILD files for gRPC testing, gRPC health checking, gRPC reflection.
172*cc02d7e2SAndroid Build Coastguard Worker- (Yet to complete) BUILD files for grpcio_tools. One test depends on this.
173*cc02d7e2SAndroid Build Coastguard Worker
174*cc02d7e2SAndroid Build Coastguard Worker## Known issues
175*cc02d7e2SAndroid Build Coastguard Worker
176*cc02d7e2SAndroid Build Coastguard Worker- [grpc/grpc #16336](https://github.com/grpc/grpc/issues/16336) RuntimeError
177*cc02d7e2SAndroid Build Coastguard Worker    for `_reconnect_test` Python unit test with Bazel
178*cc02d7e2SAndroid Build Coastguard Worker- Some tests in Bazel pass despite throwing an exception. Example:
179*cc02d7e2SAndroid Build Coastguard Worker    `testAbortedStreamStream` in
180*cc02d7e2SAndroid Build Coastguard Worker    `src/python/grpcio_tests/tests/unit/_metadata_code_details_test.py`.
181*cc02d7e2SAndroid Build Coastguard Worker- [#14557](https://github.com/grpc/grpc/pull/14557) introduced a minor bug
182*cc02d7e2SAndroid Build Coastguard Worker    where the module level loggers don't initialize a default logging handler.
183*cc02d7e2SAndroid Build Coastguard Worker- Sanity test doesn't make sense in the context of Bazel, and thus fails.
184*cc02d7e2SAndroid Build Coastguard Worker- There are some issues with Python2 vs Python3. Specifically,
185*cc02d7e2SAndroid Build Coastguard Worker  - On some machines, “cygrpc.so: undefined symbol: _Py_FalseStruct” error
186*cc02d7e2SAndroid Build Coastguard Worker    shows up. This is because of incorrect Python version being used to build
187*cc02d7e2SAndroid Build Coastguard Worker    Cython.
188*cc02d7e2SAndroid Build Coastguard Worker  - Some external packages like enum34 throw errors when used with Python 3 and
189*cc02d7e2SAndroid Build Coastguard Worker    some extra packages are currently installed as Python version in current
190*cc02d7e2SAndroid Build Coastguard Worker    build scripts. For now, the extra packages are added to a
191*cc02d7e2SAndroid Build Coastguard Worker    `requirements.bazel.txt` file in the repository root.
192