Skip to content

Commit 09cd780

Browse files
feature: demo setting env variables from plaintext yaml file
1 parent 01a025e commit 09cd780

9 files changed

Lines changed: 116 additions & 3 deletions

File tree

deps.bzl

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,15 @@ def dependencies():
1616
"https://github.com/bazelbuild/bazel-skylib/releases/download/1.4.2/bazel-skylib-1.4.2.tar.gz",
1717
],
1818
)
19+
maybe(
20+
http_archive,
21+
name = "com_github_masmovil_bazel_rules",
22+
sha256 = "9c8ac4c60da1ccda076b2a8e5194a1d4bde96bcb44808ccb75ecca33b5669102",
23+
strip_prefix = "bazel-rules-0.5.0",
24+
urls = [
25+
"https://github.com/masmovil/bazel-rules/archive/refs/tags/v0.5.0.tar.gz",
26+
],
27+
)
1928
maybe(
2029
http_archive,
2130
name = "rules_python",
@@ -36,4 +45,3 @@ def dependencies():
3645
strip_prefix = "rules_python-0.25.0",
3746
url = "https://github.com/bazelbuild/rules_python/releases/download/0.25.0/rules_python-0.25.0.tar.gz",
3847
)
39-
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
load("@pypi//:requirements.bzl", "requirement")
2+
load("@rules_python//python:defs.bzl", "py_binary", "py_test")
3+
4+
py_test(
5+
name = "test",
6+
env = { "SOPS": "sops_decrypt.yaml" },
7+
size = "small",
8+
srcs = ["test.py"],
9+
deps = [
10+
"@pypi_pyyaml//:pkg",
11+
"@rules_ai//lib/python:envexport",
12+
],
13+
data = [ "sops_decrypt.yaml" ],
14+
)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Basic Build
2+
3+
It's a habit of mine to include a basic build as part of a project; this allows me to immediately
4+
ensure the toolchains are functional and can detect sudden critical issues with the main branch's
5+
ability to build and test
6+
7+
This is almost identical to the example in rules_python, notably:
8+
- https://github.com/bazelbuild/rules_python/blob/main/examples/pip_parse @018e355
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
workspace(name = "demo_env_from_yaml")
2+
3+
# if copy-pasting, use this instead:
4+
#
5+
# load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
6+
# http_archive(
7+
# name = "rules_ai",
8+
# sha256 = "...",
9+
# strip_prefix = "rules_ai-x.y.z",
10+
# url = "https://github.com/chickenandpork/rules_ai/releases/download/x.y.z/rules_ai-x.y.z.tar.gz",
11+
# )
12+
local_repository(
13+
name = "rules_ai",
14+
path = "../..",
15+
)
16+
17+
load("@rules_ai//:deps.bzl", rules_ai_dependencies = "dependencies")
18+
19+
rules_ai_dependencies()
20+
21+
load("@com_github_masmovil_bazel_rules//repositories:repositories.bzl", mm_repositories = "repositories")
22+
mm_repositories()
23+
24+
load("@rules_ai//:python_defs.bzl", rules_ai_py_toolchain = "py_toolchain")
25+
26+
rules_ai_py_toolchain(python_version = "3.9", python_repo_name = "python39")
27+
28+
# Load a pre-curated set of default per-OS requirements, naming the repo "pypi", then (a standard
29+
# step of "rules_python" use) install the dependencies defined in this vendored requirements spec
30+
31+
load("@rules_ai//:requirements.bzl", "vendored_requirements")
32+
33+
vendored_requirements(name = "pypi")
34+
35+
load("@pypi//:requirements.bzl", "install_deps")
36+
37+
install_deps()
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
OPENAI_API_KEY: bokbokbok
2+
BOB: doug
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import unittest
2+
3+
import os
4+
from rules_ai.lib.python.envexport import env_export
5+
6+
7+
class ExampleTest(unittest.TestCase):
8+
def test_env_is_present(self):
9+
self.assertIn("OPENAI_API_KEY", os.environ)
10+
self.assertNotIn("BOB", os.environ) # "BOB" key defined in yaml file but not in `keys`
11+
12+
13+
if __name__ == "__main__":
14+
if "SOPS" in os.environ:
15+
env_export(filename=os.environ["SOPS"], keys = [ "OPENAI_API_KEY" ] )
16+
unittest.main()

lib/python/BUILD.bazel

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,3 +106,10 @@ diff_test(
106106
"@platforms//os:windows": ":make_platform_agnostic_windows",
107107
}),
108108
)
109+
110+
py_library(
111+
name = "envexport",
112+
srcs = ["envexport.py"],
113+
visibility = ["//visibility:public"],
114+
#deps = [ ]
115+
)

lib/python/envexport.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import yaml
2+
import re
3+
import os
4+
5+
def env_export(filename, keys):
6+
"""Load a yaml file <filename> and set environment variables from the list <keys> from k/v in
7+
the file.
8+
9+
Intended use is like importing specific k/v from a yaml file to the env, such as specific
10+
secrets by key from a decrypted SOPS file.
11+
12+
parameters:
13+
- filename: a filename such as "my/secrets.yaml"
14+
- keys: list of keys such as [ "OPENAI_API_KEY", "PROMPTLAYER_KEY" ]
15+
"""
16+
17+
with open(filename, 'r') as file:
18+
p = yaml.load(file, Loader=yaml.FullLoader)
19+
for k in keys:
20+
if k in p.keys():
21+
os.environ[k] = p[k]
22+
23+

python_defs.bzl

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,3 @@ def py_toolchain(python_version = "3.9", python_repo_name = "python39"):
1515

1616
# Because we drop out the pip_parse(), we need to explicitly call one of the magic hidden helper-functions:
1717
pip_install_dependencies()
18-
19-

0 commit comments

Comments
 (0)