Skip to content

Commit b332988

Browse files
authored
Hermetic Python 3 runtime by building from source + jupyter notebook (UBC-Thunderbots#1828)
* pull python3 and build it in bazel for a hermetic python runtime * pull python3 and build it in bazel for a hermetic python runtime * run jupyter * remvoe macos stuff for python build and make the python build a little faster
1 parent 037b940 commit b332988

9 files changed

+102
-15
lines changed

environment_setup/setup_software.sh

+1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ host_software_packages=(
5858
python3-yaml # Load dynamic parameter configuration files
5959
qt5-default # The GUI library for our visualizer
6060
valgrind # Checks for memory leaks
61+
libsqlite3-dev # needed to build Python 3 with sqlite support
6162
)
6263

6364
if [[ $(lsb_release -rs) == "20.04" ]]; then

src/BUILD

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
load("@rules_python//python:defs.bzl", "py_runtime")
2+
load("@rules_python//python:defs.bzl", "py_runtime_pair")
3+
4+
# targets for hermetic Python runtime
5+
py_runtime(
6+
name = "python3_runtime",
7+
files = ["@python_interpreter//:files"],
8+
interpreter = "@python_interpreter//:python_bin",
9+
python_version = "PY3",
10+
visibility = ["//visibility:public"],
11+
)
12+
13+
py_runtime_pair(
14+
name = "py_runtime_pair",
15+
py2_runtime = None,
16+
py3_runtime = ":python3_runtime",
17+
)
18+
19+
toolchain(
20+
name = "py_toolchain",
21+
toolchain = ":py_runtime_pair",
22+
toolchain_type = "@bazel_tools//tools/python:toolchain_type",
23+
)

src/WORKSPACE

+44-14
Original file line numberDiff line numberDiff line change
@@ -192,35 +192,65 @@ http_archive(
192192

193193
git_repository(
194194
name = "rules_python",
195-
commit = "a0fbf98d4e3a232144df4d0d80b577c7a693b570",
195+
commit = "c8c79aae9aa1b61d199ad03d5fe06338febd0774",
196196
remote = "https://github.com/bazelbuild/rules_python.git",
197197
shallow_since = "1586444447 +0200",
198198
)
199199

200-
load("@rules_python//python:repositories.bzl", "py_repositories")
200+
# Based on the hermetic Python 3 guide found here
201+
# https://thethoughtfulkoala.com/posts/2020/05/16/bazel-hermetic-python.html
202+
_py_configure = "./configure --prefix=$(pwd)/bazel_install"
201203

202-
py_repositories()
204+
http_archive(
205+
name = "python_interpreter",
206+
build_file_content = """
207+
exports_files(["python_bin"])
208+
filegroup(
209+
name = "files",
210+
srcs = glob(["bazel_install/**"], exclude = ["**/* *"]),
211+
visibility = ["//visibility:public"],
212+
)
213+
""",
214+
patch_cmds = [
215+
"mkdir $(pwd)/bazel_install",
216+
_py_configure,
217+
"make -j$(nproc)",
218+
"make install",
219+
"ln -s bazel_install/bin/python3 python_bin",
220+
],
221+
sha256 = "91923007b05005b5f9bd46f3b9172248aea5abc1543e8a636d59e629c3331b01",
222+
strip_prefix = "Python-3.7.9",
223+
urls = ["https://www.python.org/ftp/python/3.7.9/Python-3.7.9.tar.xz"],
224+
)
203225

204-
load("@rules_python//python:pip.bzl", "pip_repositories")
226+
register_toolchains("//:py_toolchain")
205227

206-
pip_repositories()
228+
load("@rules_python//python:repositories.bzl", "py_repositories")
207229

208-
load("@rules_python//python:pip.bzl", "pip3_import")
230+
py_repositories()
231+
232+
load("@rules_python//python:pip.bzl", "pip_install")
209233

210-
pip3_import(
234+
pip_install(
211235
name = "python_control_deps",
236+
python_interpreter_target = "@python_interpreter//:python_bin",
212237
requirements = "//firmware/app/control/python_controller:requirements.txt",
213238
)
214239

215-
load("@python_control_deps//:requirements.bzl", "pip_install")
216-
217-
pip_install()
218-
219-
pip3_import(
240+
pip_install(
220241
name = "dynamic_parameter_deps",
242+
python_interpreter_target = "@python_interpreter//:python_bin",
221243
requirements = "//shared/parameter_v2/generation_scripts:requirements.txt",
222244
)
223245

224-
load("@dynamic_parameter_deps//:requirements.bzl", "pip_install")
246+
pip_install(
247+
name = "nanopb_deps",
248+
python_interpreter_target = "@python_interpreter//:python_bin",
249+
requirements = "//external:nanopb_requirements.txt",
250+
)
225251

226-
pip_install()
252+
pip_install(
253+
name = "python_tools_deps",
254+
python_interpreter_target = "@python_interpreter//:python_bin",
255+
requirements = "//python_tools:requirements.txt",
256+
)

src/external/nanopb.BUILD

+5-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ exports_files(["LICENSE.txt"])
44

55
package(default_visibility = ["//visibility:public"])
66

7+
load("@nanopb_deps//:requirements.bzl", "requirement")
8+
79
common_defines = [
810
# By default, NanoPb only supports 8-bit tags. This define changes the tag type to
911
# one that supports 16-bit tags.
@@ -52,7 +54,9 @@ cc_library(
5254
py_binary(
5355
name = "nanopb_generator",
5456
srcs = ["generator/nanopb_generator.py"],
55-
imports = ["proto"],
57+
deps = [
58+
requirement("protobuf"),
59+
],
5660
)
5761

5862
proto_library(

src/external/nanopb_requirements.txt

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
protobuf==3.6.1

src/python_tools/BUILD

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package(default_visibility = ["//visibility:public"])
2+
3+
load("@python_tools_deps//:requirements.bzl", "requirement")
4+
5+
py_test(
6+
name = "test_hermetic_python_environment",
7+
srcs = ["test_hermetic_python_environment.py"],
8+
)
9+
10+
py_binary(
11+
name = "jupyter",
12+
srcs = ["jupyter.py"],
13+
deps = [
14+
requirement("jupyter"),
15+
requirement("notebook"),
16+
],
17+
)

src/python_tools/jupyter.py

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from notebook.notebookapp import main
2+
import sys
3+
4+
if __name__ == "__main__":
5+
sys.exit(main())

src/python_tools/requirements.txt

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
jupyter==1.0.0
2+
notebook==6.1.5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import sys
2+
3+
# a basic test to make sure we're not running the system python interpreter
4+
assert "/usr/bin/python" not in sys.executable

0 commit comments

Comments
 (0)