Show one option for end-to-end usage
diff --git a/examples/poetry/BUILD.bazel b/examples/poetry/BUILD.bazel
new file mode 100644
index 0000000..3ecdbe4
--- /dev/null
+++ b/examples/poetry/BUILD.bazel
@@ -0,0 +1,53 @@
+load("@aspect_bazel_lib//lib:copy_to_bin.bzl", "copy_to_bin")
+load("@aspect_bazel_lib//lib:run_binary.bzl", "run_binary")
+load("@aspect_bazel_lib//lib:write_source_files.bzl", "write_source_file")
+load("@pypi//:requirements.bzl", "requirement")
+load("@rules_python//python:defs.bzl", "py_binary")
+
+# METHOD 1 (see README.md)
+# run `poetry export` as an action and write_source_files back to src
+# BUT how to get the ones for other platforms updated??
+#
+copy_to_bin(
+    name = "copy_poetry_inputs",
+    srcs = [
+        "poetry.lock",
+        "pyproject.toml",
+    ],
+)
+
+run_binary(
+    name = "poetry_export",
+    srcs = [":copy_poetry_inputs"],
+    outs = ["requirements.txt"],
+    args = [
+        "export",
+        "--directory",
+        "$(RULEDIR)",
+        "--output",
+        "$(location requirements.txt)",
+    ],
+    tool = "@poetry_poetry//:bin",
+)
+
+[
+    write_source_file(
+        name = "vendor_{}_requirements".format(os),
+        in_file = ":requirements.txt",
+        out_file = "requirements_{}.txt".format(os),
+        target_compatible_with = ["@platforms//os:" + os],
+    )
+    for os in [
+        "macos",
+        "linux",
+        "windows",
+    ]
+]
+
+# Prove that it worked
+
+py_binary(
+    name = "main",
+    srcs = ["main.py"],
+    deps = [requirement("pendulum")],
+)
diff --git a/examples/poetry/README.md b/examples/poetry/README.md
index 2a62d01..7325077 100644
--- a/examples/poetry/README.md
+++ b/examples/poetry/README.md
@@ -35,4 +35,7 @@
 
 To illustrate the translation, you can `bazel run @poetry_poetry//:bin export` to write a `requirements.txt` file to stdout. This is what we do internally.
 
-TODO: write a `poetry_export` repository rule around it?
+TODO: figure out the workflow:
+
+1. vendor the requirements.txt files into the repo, nice because it avoids work in a repo rule, but reintroduces the problem of having to write the macos file on macos, etc. We want it to be based on the host platform automatically?
+2. write a `poetry_export` repository rule around it, but how to execute a py_binary from a repo rule? See /poetry/defs.bzl
diff --git a/examples/poetry/WORKSPACE.bazel b/examples/poetry/WORKSPACE.bazel
index 221e54c..a6bac24 100644
--- a/examples/poetry/WORKSPACE.bazel
+++ b/examples/poetry/WORKSPACE.bazel
@@ -4,6 +4,13 @@
     name = "rules_python",
     path = "../..",
 )
+load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
+http_archive(
+    name = "aspect_bazel_lib",
+    sha256 = "e3151d87910f69cf1fc88755392d7c878034a69d6499b287bcfc00b1cf9bb415",
+    strip_prefix = "bazel-lib-1.32.1",
+    url = "https://github.com/aspect-build/bazel-lib/releases/download/v1.32.1/bazel-lib-v1.32.1.tar.gz",
+)
 
 load("@rules_python//python:repositories.bzl", "py_repositories", "python_register_toolchains")
 
@@ -27,22 +34,32 @@
     python_interpreter_target = interpreter,
 )
 
+load("@rules_python//python:pip.bzl", "pip_parse")
 
-# TODO:
+# METHOD 1 (see README.md)
+
+# load("@rules_python//poetry:defs.bzl", "poetry_export")
+#
 # poetry_export(
 #    name = "poetry_deps",
-#    lockfile=poetry.lock
-#)
-
-# load("@rules_python//python:pip.bzl", "pip_parse")
+#    lockfile = "//:poetry.lock",
+# )
+#
 # pip_parse(
-#     name = "pip",
-#     requirements_txt = "@poetry_deps//:requirements.txt",
+#     name = "pypi",
+#     requirements_lock = "@poetry_deps//:requirements.txt",
 # )
 
-# OR MAYBE syntax sugar, as pip parse could parse more formats?
+# METHOD 2 (see README.md)
 
-# pip_parse(
-#   name = "pip",
-#   poetry_lock = "poetry.lock",
-# )
+pip_parse(
+    name = "pypi",
+    requirements_darwin = "//:requirements_macos.txt",
+    requirements_linux = "//:requirements_linux.txt",
+    requirements_lock = "//:requirements_linux.txt",
+    requirements_windows = "//:requirements_windows.txt",
+)
+
+load("@pypi//:requirements.bzl", "install_deps")
+
+install_deps(python_interpreter_target = interpreter)
\ No newline at end of file
diff --git a/examples/poetry/main.py b/examples/poetry/main.py
new file mode 100644
index 0000000..246dd99
--- /dev/null
+++ b/examples/poetry/main.py
@@ -0,0 +1,14 @@
+import pendulum
+
+now = pendulum.now("Europe/Paris")
+
+# Changing timezone
+now.in_timezone("America/Toronto")
+
+# Default support for common datetime formats
+now.to_iso8601_string()
+
+# Shifting
+now.add(days=2)
+
+print(now)
diff --git a/examples/poetry/requirements_linux.txt b/examples/poetry/requirements_linux.txt
new file mode 100644
index 0000000..b59907d
--- /dev/null
+++ b/examples/poetry/requirements_linux.txt
@@ -0,0 +1,31 @@
+pendulum==2.1.2 ; python_version >= "3.10" and python_version < "4.0" \
+    --hash=sha256:0731f0c661a3cb779d398803655494893c9f581f6488048b3fb629c2342b5394 \
+    --hash=sha256:1245cd0075a3c6d889f581f6325dd8404aca5884dea7223a5566c38aab94642b \
+    --hash=sha256:29c40a6f2942376185728c9a0347d7c0f07905638c83007e1d262781f1e6953a \
+    --hash=sha256:2d1619a721df661e506eff8db8614016f0720ac171fe80dda1333ee44e684087 \
+    --hash=sha256:318f72f62e8e23cd6660dbafe1e346950281a9aed144b5c596b2ddabc1d19739 \
+    --hash=sha256:33fb61601083f3eb1d15edeb45274f73c63b3c44a8524703dc143f4212bf3269 \
+    --hash=sha256:3481fad1dc3f6f6738bd575a951d3c15d4b4ce7c82dce37cf8ac1483fde6e8b0 \
+    --hash=sha256:4c9c689747f39d0d02a9f94fcee737b34a5773803a64a5fdb046ee9cac7442c5 \
+    --hash=sha256:7c5ec650cb4bec4c63a89a0242cc8c3cebcec92fcfe937c417ba18277d8560be \
+    --hash=sha256:94b1fc947bfe38579b28e1cccb36f7e28a15e841f30384b5ad6c5e31055c85d7 \
+    --hash=sha256:9702069c694306297ed362ce7e3c1ef8404ac8ede39f9b28b7c1a7ad8c3959e3 \
+    --hash=sha256:b06a0ca1bfe41c990bbf0c029f0b6501a7f2ec4e38bfec730712015e8860f207 \
+    --hash=sha256:b6c352f4bd32dff1ea7066bd31ad0f71f8d8100b9ff709fb343f3b86cee43efe \
+    --hash=sha256:c501749fdd3d6f9e726086bf0cd4437281ed47e7bca132ddb522f86a1645d360 \
+    --hash=sha256:c807a578a532eeb226150d5006f156632df2cc8c5693d778324b43ff8c515dd0 \
+    --hash=sha256:db0a40d8bcd27b4fb46676e8eb3c732c67a5a5e6bfab8927028224fbced0b40b \
+    --hash=sha256:de42ea3e2943171a9e95141f2eecf972480636e8e484ccffaf1e833929e9e052 \
+    --hash=sha256:e95d329384717c7bf627bf27e204bc3b15c8238fa8d9d9781d93712776c14002 \
+    --hash=sha256:f5e236e7730cab1644e1b87aca3d2ff3e375a608542e90fe25685dae46310116 \
+    --hash=sha256:f888f2d2909a414680a29ae74d0592758f2b9fcdee3549887779cd4055e975db \
+    --hash=sha256:fb53ffa0085002ddd43b6ca61a7b34f2d4d7c3ed66f931fe599e1a531b42af9b
+python-dateutil==2.8.2 ; python_version >= "3.10" and python_version < "4.0" \
+    --hash=sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86 \
+    --hash=sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9
+pytzdata==2020.1 ; python_version >= "3.10" and python_version < "4.0" \
+    --hash=sha256:3efa13b335a00a8de1d345ae41ec78dd11c9f8807f522d39850f2dd828681540 \
+    --hash=sha256:e1e14750bcf95016381e4d472bad004eef710f2d6417240904070b3d6654485f
+six==1.16.0 ; python_version >= "3.10" and python_version < "4.0" \
+    --hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \
+    --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254
diff --git a/examples/poetry/requirements_macos.txt b/examples/poetry/requirements_macos.txt
new file mode 100644
index 0000000..6fe8fd6
--- /dev/null
+++ b/examples/poetry/requirements_macos.txt
@@ -0,0 +1 @@
+¯\_(ツ)_/¯
\ No newline at end of file
diff --git a/examples/poetry/requirements_windows.txt b/examples/poetry/requirements_windows.txt
new file mode 100644
index 0000000..6fe8fd6
--- /dev/null
+++ b/examples/poetry/requirements_windows.txt
@@ -0,0 +1 @@
+¯\_(ツ)_/¯
\ No newline at end of file
diff --git a/poetry/defs.bzl b/poetry/defs.bzl
new file mode 100644
index 0000000..e672011
--- /dev/null
+++ b/poetry/defs.bzl
@@ -0,0 +1,32 @@
+"""Repository rule that can export a poetry.lock to a requirements.txt for the host platform
+
+(or the exec platform, if you're using RBE-hosted repo rule execution?)
+"""
+
+def _poetry_export_impl(rctx):
+    # FIXME: this doesn't work!!
+    bin = rctx.path(rctx.attr.poetry_bin)
+    cmd = [bin, "export"]
+
+    for group in rctx.attr.groups:
+        cmd.append("--with=" + group)
+
+    result = rctx.execute(
+        cmd,
+        working_directory = str(rctx.path(rctx.attr.lockfile).dirname),
+    )
+
+    if result.return_code != 0:
+        fail("Failed to execute poetry. Error: ", result.stderr)
+
+    rctx.file("requirements_lock.txt", result.stdout)
+    rctx.file("BUILD", "# no targets")
+
+poetry_export = repository_rule(
+    implementation = _poetry_export_impl,
+    attrs = {
+        "groups": attr.string_list(default = ["dev"]),
+        "lockfile": attr.label(allow_single_file = [".lock"], mandatory = True),
+        "poetry_bin": attr.label(default = "@poetry_poetry//:bin"),
+    },
+)