Replace rules_pip with rules_python; use bazel built upstream grpc
instead of Python packages

As usual with Python sadness, the @pydeps wheels are built on the bazel
host, so stuffing them inside a container_image (or py_image) will cause
new and unexpected kinds of misery.

Change-Id: Id4e4d53741cf2da367f01aa15c21c133c5cf0dba
diff --git a/WORKSPACE b/WORKSPACE
index d3079bf..9474e10 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -5,6 +5,19 @@
 load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
 load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
 
+# Protobuf deps (shared between many rules).
+# Load this as early as possible, to avoid a different version being pulled in by deps of something else
+
+http_archive(
+    name = "com_google_protobuf",
+    sha256 = "bb8ce9ba11eb7bccf080599fe7cad9cc461751c8dd1ba61701c0070d58cde973",
+    strip_prefix = "protobuf-3.12.2",
+    urls = ["https://github.com/google/protobuf/archive/v3.12.2.tar.gz"],
+)
+
+load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps")
+protobuf_deps()
+
 # Go/Gazelle rules
 
 http_archive(
@@ -25,18 +38,43 @@
     ],
 )
 
-# Protobuf deps (shared between many rules).
+# Python rules
+
+# Important: rules_python must be loaded before protobuf (and grpc) because they load an older version otherwise
 
 http_archive(
-    name = "com_google_protobuf",
-    sha256 = "9748c0d90e54ea09e5e75fb7fac16edce15d2028d4356f32211cfa3c0e956564",
-    strip_prefix = "protobuf-3.11.4",
-    urls = ["https://github.com/protocolbuffers/protobuf/archive/v3.11.4.zip"],
+    name = "rules_python",
+    url = "https://github.com/bazelbuild/rules_python/releases/download/0.0.2/rules_python-0.0.2.tar.gz",
+    strip_prefix = "rules_python-0.0.2",
+    sha256 = "b5668cde8bb6e3515057ef465a35ad712214962f0b3a314e551204266c7be90c",
+)
+load("@rules_python//python:repositories.bzl", "py_repositories")
+py_repositories()
+
+load("@rules_python//python:pip.bzl", "pip_repositories")
+pip_repositories()
+
+load("@rules_python//python:pip.bzl", "pip3_import")
+pip3_import(
+   name = "pydeps",
+   requirements = "//third_party/py:requirements.txt",
 )
 
-load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps")
+load("@pydeps//:requirements.bzl", "pip_install")
+pip_install()
 
-protobuf_deps()
+# IMPORTANT: match protobuf version above with the one loaded by grpc
+http_archive(
+    name = "com_github_grpc_grpc",
+    sha256 = "419dba362eaf8f1d36849ceee17c3e2ff8ff12ac666b42d3ff02a164ebe090e9",
+    strip_prefix = "grpc-1.30.0",
+    urls = ["https://github.com/grpc/grpc/archive/v1.30.0.tar.gz"],
+)
+
+load("@com_github_grpc_grpc//bazel:grpc_deps.bzl", "grpc_deps")
+grpc_deps()
+load("@com_github_grpc_grpc//bazel:grpc_extra_deps.bzl", "grpc_extra_deps")
+grpc_extra_deps()
 
 # Go rules dependencies and our own dependencies.
 
@@ -74,28 +112,6 @@
 )
 container_repositories()
 
-# Python rules
-
-git_repository(
-    name = "com_apt_itude_rules_pip",
-    commit = "186bade4f054c0a9be7037585584c9c572cba483",
-    remote = "https://github.com/apt-itude/rules_pip.git",
-    shallow_since = "1564255337 -0400"
-)
-
-# Python dependencies
-load("@com_apt_itude_rules_pip//rules:dependencies.bzl", "pip_rules_dependencies")
-pip_rules_dependencies()
-
-load("@com_apt_itude_rules_pip//rules:repository.bzl", "pip_repository")
-pip_repository(
-    name = "pydeps",
-    requirements = "//third_party/py:requirements-lock.json",
-)
-
-load("@pydeps//:requirements.bzl", "pip_install")
-
-
 # Docker base images
 
 load("@io_bazel_rules_docker//container:container.bzl", "container_pull")
diff --git a/bgpwtf/cccampix/BUILD b/bgpwtf/cccampix/BUILD
index a96f739..205289f 100644
--- a/bgpwtf/cccampix/BUILD
+++ b/bgpwtf/cccampix/BUILD
@@ -1,5 +1,6 @@
 load("@io_bazel_rules_docker//container:container.bzl", "container_image", "container_layer", "container_push")
 load("@subpar//:subpar.bzl", "par_binary")
+load("@pydeps//:requirements.bzl", "requirement")
 
 par_binary(
     name = "ripe-sync",
@@ -7,9 +8,9 @@
         "ripe-sync.py",
     ],
     deps = [
-        "@pydeps//grpcio",
-        "@pydeps//requests",
+        requirement("requests"),
         "//bgpwtf/cccampix/proto:ix_py_proto",
+        "//bgpwtf/cccampix/proto:ix_grpc_proto",
     ],
     legacy_create_init = False,
     zip_safe = False,
diff --git a/bgpwtf/cccampix/frontend/BUILD.bazel b/bgpwtf/cccampix/frontend/BUILD.bazel
index 6fae1d3..f9bbd90 100644
--- a/bgpwtf/cccampix/frontend/BUILD.bazel
+++ b/bgpwtf/cccampix/frontend/BUILD.bazel
@@ -1,4 +1,5 @@
 load("@subpar//:subpar.bzl", "par_binary")
+load("@pydeps//:requirements.bzl", "requirement")
 
 py_library(
     name = "frontend_lib",
@@ -10,10 +11,12 @@
         "templates/**",
     ]),
     deps = [
-        "@pydeps//arrow",
-        "@pydeps//flask",
-        "@pydeps//grpcio",
+        requirement("arrow"),
+        requirement("flask"),
+        requirement("werkzeug"),
+        requirement("itsdangerous"),
         "//bgpwtf/cccampix/proto:ix_py_proto",
+        "//bgpwtf/cccampix/proto:ix_grpc_proto",
     ],
 )
 
@@ -36,13 +39,14 @@
     ],
     deps = [
         ":frontend_lib",
-        "@pydeps//gevent",
-        "@pydeps//gunicorn",
+        requirement("gevent"),
+        requirement("gunicorn"),
+        requirement("greenlet"),
     ],
     visibility = [
         "//bgpwtf/cccampix:__pkg__",
     ],
     legacy_create_init = False,
     zip_safe = False,
-    no_remove = True,
+    #no_remove = True,
 )
diff --git a/bgpwtf/cccampix/proto/BUILD.bazel b/bgpwtf/cccampix/proto/BUILD.bazel
index 22c557e..740fef7 100644
--- a/bgpwtf/cccampix/proto/BUILD.bazel
+++ b/bgpwtf/cccampix/proto/BUILD.bazel
@@ -1,6 +1,7 @@
 load("@io_bazel_rules_go//go:def.bzl", "go_library")
 load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
-load("@build_stack_rules_proto//python:python_grpc_compile.bzl", "python_grpc_compile")
+load("@com_github_grpc_grpc//bazel:python_rules.bzl", "py_proto_library", "py_grpc_library")
+
 
 proto_library(
     name = "ix_proto",
@@ -23,16 +24,15 @@
     visibility = ["//visibility:public"],
 )
 
-python_grpc_compile(
-    name = "ix_py_proto_src",
+py_proto_library(
+    name = "ix_py_proto",
     deps = [":ix_proto"],
+    visibility = ["//visibility:public"],
 )
 
-py_library(
-    name = "ix_py_proto",
-    srcs = ["ix_py_proto_src"],
+py_grpc_library(
+    name = "ix_grpc_proto",
+    srcs = [":ix_proto"],
+    deps = [":ix_py_proto"],
     visibility = ["//visibility:public"],
-    deps = [
-        "@pydeps//protobuf",
-    ],
 )
diff --git a/cluster/clustercfg/BUILD b/cluster/clustercfg/BUILD
index eef2049..d83a921 100644
--- a/cluster/clustercfg/BUILD
+++ b/cluster/clustercfg/BUILD
@@ -1,3 +1,5 @@
+load("@pydeps//:requirements.bzl", "requirement")
+
 py_binary(
     name = "clustercfg",
     python_version = "PY3",
@@ -7,7 +9,8 @@
     ],
     visibility = ["//visibility:public"],
     deps = [
-        "@pydeps//fabric",
+        requirement("fabric"),
+        requirement("asn1crypto"),
         "//tools:secretstore_lib",
     ],
 )
diff --git a/hswaw/lib/flask_spaceauth/BUILD b/hswaw/lib/flask_spaceauth/BUILD
index 9060d58..4c29872 100644
--- a/hswaw/lib/flask_spaceauth/BUILD
+++ b/hswaw/lib/flask_spaceauth/BUILD
@@ -1,8 +1,12 @@
+load("@pydeps//:requirements.bzl", "requirement")
+
 py_binary(
     name = "example",
     srcs = ["example.py"],
     deps = [
         "//hswaw/lib/flask_spaceauth/spaceauth",
-        "@pydeps//flask",
+        requirement("flask"),
+        requirement("werkzeug"),
+        requirement("itsdangerous"),
     ]
 )
diff --git a/hswaw/lib/flask_spaceauth/spaceauth/BUILD b/hswaw/lib/flask_spaceauth/spaceauth/BUILD
index 94c1591..ee3d670 100644
--- a/hswaw/lib/flask_spaceauth/spaceauth/BUILD
+++ b/hswaw/lib/flask_spaceauth/spaceauth/BUILD
@@ -1,3 +1,5 @@
+load("@pydeps//:requirements.bzl", "requirement")
+
 py_library(
     name = "spaceauth",
     srcs = [
@@ -6,8 +8,8 @@
     ],
     visibility = ["//visibility:public"],
     deps = [
-        "@pydeps//blinker",
-        "@pydeps//flask_login",
-        "@pydeps//flask_oauthlib",
+        requirement("blinker"),
+        requirement("flask_login"),
+        requirement("flask_oauthlib"),
     ],
 )
diff --git a/personal/q3k/BUILD b/personal/q3k/BUILD
index 99e661d..8317e7c 100644
--- a/personal/q3k/BUILD
+++ b/personal/q3k/BUILD
@@ -1,7 +1,9 @@
+load("@pydeps//:requirements.bzl", "requirement")
+
 py_binary(
     name = "django-admin",
     srcs = ["django-admin.py"],
     deps = [
-        "@pydeps36//django",
+        requirement("django"),
     ]
 )
diff --git a/personal/q3k/djtest/BUILD b/personal/q3k/djtest/BUILD
index b3a2cad..d4ab6cc 100644
--- a/personal/q3k/djtest/BUILD
+++ b/personal/q3k/djtest/BUILD
@@ -1,8 +1,11 @@
+load("@pydeps//:requirements.bzl", "requirement")
+
 py_library(
     name = "app",
     srcs = glob(["djtest/**/*.py"]),
     deps = [
-        "@pydeps//django",
+        requirement("django"),
+        requirement("sqlparse"),
     ],
 )
 
@@ -20,8 +23,6 @@
     deps = [
        ":app",
        "@bazel_tools//tools/python/runfiles",
-    ],
-    data = [
-        '@pip__uWSGI_2_0_18_cp36_cp36m_linux_x86_64//scripts:uwsgi',
+        requirement("uwsgi"),
     ],
 )
diff --git a/personal/q3k/djtest/uwsgi-start.py b/personal/q3k/djtest/uwsgi-start.py
index 0edcdaf..eb22d55 100644
--- a/personal/q3k/djtest/uwsgi-start.py
+++ b/personal/q3k/djtest/uwsgi-start.py
@@ -9,7 +9,7 @@
 from bazel_tools.tools.python.runfiles import runfiles
 r = runfiles.Create()
 
-uwsgi = r.Rlocation("pip__uWSGI_2_0_18_cp36_cp36m_linux_x86_64/scripts/uwsgi")
+uwsgi = r.Rlocation("pydeps_pypi__uWSGI_2_0_18/uWSGI-2.0.18.data/scripts/uwsgi")
 print(uwsgi)
 settings = r.Rlocation("hscloud/personal/q3k/djtest/djtest/settings.py")
 print(settings)
diff --git a/third_party/py/BUILD b/third_party/py/BUILD
index 56b5534..e69de29 100644
--- a/third_party/py/BUILD
+++ b/third_party/py/BUILD
@@ -1,7 +0,0 @@
-load("@com_apt_itude_rules_pip//rules:lock.bzl", "pip_lock")
-
-pip_lock(
-    name = "lock",
-    requirements = ["requirements.txt"],
-    python_version = "PY3",
-)
diff --git a/third_party/py/requirements-lock.json b/third_party/py/requirements-lock.json
deleted file mode 100644
index a3296d4..0000000
--- a/third_party/py/requirements-lock.json
+++ /dev/null
@@ -1,528 +0,0 @@
-{
-  "environments": {
-    "linux_py3": {
-      "python_version": 3,
-      "requirements": {
-        "arrow": {
-          "dependencies": [
-            "python-dateutil"
-          ],
-          "is_direct": true,
-          "source": "arrow_0_14_5_py2_py3_none_any",
-          "version": "0.14.5"
-        },
-        "asn1crypto": {
-          "dependencies": [],
-          "is_direct": true,
-          "source": "asn1crypto_0_24_0_py2_py3_none_any",
-          "version": "0.24.0"
-        },
-        "bcrypt": {
-          "dependencies": [
-            "cffi",
-            "six"
-          ],
-          "is_direct": true,
-          "source": "bcrypt_3_1_5_cp34_abi3_manylinux1_x86_64",
-          "version": "3.1.5"
-        },
-        "blinker": {
-          "dependencies": [],
-          "is_direct": true,
-          "source": "blinker_1_4_py3_none_any",
-          "version": "1.4"
-        },
-        "certifi": {
-          "dependencies": [],
-          "is_direct": true,
-          "source": "certifi_2019_6_16_py2_py3_none_any",
-          "version": "2019.6.16"
-        },
-        "cffi": {
-          "dependencies": [
-            "pycparser"
-          ],
-          "is_direct": true,
-          "source": "cffi_1_11_5_cp36_cp36m_manylinux1_x86_64",
-          "version": "1.11.5"
-        },
-        "chardet": {
-          "dependencies": [],
-          "is_direct": true,
-          "source": "chardet_3_0_4_py2_py3_none_any",
-          "version": "3.0.4"
-        },
-        "click": {
-          "dependencies": [],
-          "is_direct": true,
-          "source": "Click_7_0_py2_py3_none_any",
-          "version": "7.0"
-        },
-        "cockroachdb": {
-          "dependencies": [],
-          "is_direct": true,
-          "source": "cockroachdb_0_3_3_py3_none_any",
-          "version": "0.3.3"
-        },
-        "cryptography": {
-          "dependencies": [
-            "asn1crypto",
-            "cffi",
-            "idna",
-            "six"
-          ],
-          "is_direct": true,
-          "source": "cryptography_2_4_2_cp34_abi3_manylinux1_x86_64",
-          "version": "2.4.2"
-        },
-        "django": {
-          "dependencies": [
-            "pytz",
-            "sqlparse"
-          ],
-          "is_direct": true,
-          "source": "Django_2_2_3_py3_none_any",
-          "version": "2.2.3"
-        },
-        "fabric": {
-          "dependencies": [
-            "cryptography",
-            "invoke",
-            "paramiko"
-          ],
-          "is_direct": true,
-          "source": "fabric_2_4_0_py2_py3_none_any",
-          "version": "2.4.0"
-        },
-        "flask": {
-          "dependencies": [
-            "click",
-            "itsdangerous",
-            "jinja2",
-            "werkzeug"
-          ],
-          "is_direct": true,
-          "source": "Flask_1_1_1_py2_py3_none_any",
-          "version": "1.1.1"
-        },
-        "flask-login": {
-          "dependencies": [
-            "flask"
-          ],
-          "is_direct": true,
-          "source": "Flask_Login_0_4_1_py2_py3_none_any",
-          "version": "0.4.1"
-        },
-        "flask-oauthlib": {
-          "dependencies": [
-            "flask",
-            "oauthlib",
-            "requests-oauthlib"
-          ],
-          "is_direct": true,
-          "source": "Flask_OAuthlib_0_9_5_py3_none_any",
-          "version": "0.9.5"
-        },
-        "flask-sqlalchemy": {
-          "dependencies": [
-            "flask",
-            "sqlalchemy"
-          ],
-          "is_direct": true,
-          "source": "Flask_SQLAlchemy_2_4_0_py2_py3_none_any",
-          "version": "2.4.0"
-        },
-        "flask-wtf": {
-          "dependencies": [
-            "flask",
-            "wtforms"
-          ],
-          "is_direct": true,
-          "source": "Flask_WTF_0_14_2_py2_py3_none_any",
-          "version": "0.14.2"
-        },
-        "future": {
-          "dependencies": [],
-          "is_direct": true,
-          "source": "future_0_17_1_py3_none_any",
-          "version": "0.17.1"
-        },
-        "gevent": {
-          "dependencies": [
-            "greenlet"
-          ],
-          "is_direct": true,
-          "source": "gevent_1_4_0_cp36_cp36m_manylinux1_x86_64",
-          "version": "1.4.0"
-        },
-        "greenlet": {
-          "dependencies": [],
-          "is_direct": true,
-          "source": "greenlet_0_4_15_cp36_cp36m_manylinux1_x86_64",
-          "version": "0.4.15"
-        },
-        "grpcio": {
-          "dependencies": [
-            "six"
-          ],
-          "is_direct": true,
-          "source": "grpcio_1_22_0_cp36_cp36m_manylinux1_x86_64",
-          "version": "1.22.0"
-        },
-        "gunicorn": {
-          "dependencies": [],
-          "is_direct": true,
-          "source": "gunicorn_19_9_0_py2_py3_none_any",
-          "version": "19.9.0"
-        },
-        "idna": {
-          "dependencies": [],
-          "is_direct": true,
-          "source": "idna_2_8_py2_py3_none_any",
-          "version": "2.8"
-        },
-        "invoke": {
-          "dependencies": [],
-          "is_direct": true,
-          "source": "invoke_1_2_0_py3_none_any",
-          "version": "1.2.0"
-        },
-        "itsdangerous": {
-          "dependencies": [],
-          "is_direct": true,
-          "source": "itsdangerous_1_1_0_py2_py3_none_any",
-          "version": "1.1.0"
-        },
-        "jinja2": {
-          "dependencies": [
-            "markupsafe"
-          ],
-          "is_direct": true,
-          "source": "Jinja2_2_10_1_py2_py3_none_any",
-          "version": "2.10.1"
-        },
-        "markupsafe": {
-          "dependencies": [],
-          "is_direct": true,
-          "source": "MarkupSafe_1_1_1_cp36_cp36m_manylinux1_x86_64",
-          "version": "1.1.1"
-        },
-        "oauthlib": {
-          "dependencies": [],
-          "is_direct": true,
-          "source": "oauthlib_2_1_0_py2_py3_none_any",
-          "version": "2.1.0"
-        },
-        "paramiko": {
-          "dependencies": [
-            "bcrypt",
-            "cryptography",
-            "pyasn1",
-            "pynacl"
-          ],
-          "is_direct": true,
-          "source": "paramiko_2_4_2_py2_py3_none_any",
-          "version": "2.4.2"
-        },
-        "protobuf": {
-          "dependencies": [
-            "setuptools",
-            "six"
-          ],
-          "is_direct": true,
-          "source": "protobuf_3_9_0_cp36_cp36m_manylinux1_x86_64",
-          "version": "3.9.0"
-        },
-        "psycopg2": {
-          "dependencies": [],
-          "is_direct": true,
-          "source": "psycopg2_2_7_7_cp36_cp36m_manylinux1_x86_64",
-          "version": "2.7.7"
-        },
-        "pyasn1": {
-          "dependencies": [],
-          "is_direct": true,
-          "source": "pyasn1_0_4_5_py2_py3_none_any",
-          "version": "0.4.5"
-        },
-        "pycparser": {
-          "dependencies": [],
-          "is_direct": true,
-          "source": "pycparser_2_19_py2_py3_none_any",
-          "version": "2.19"
-        },
-        "pynacl": {
-          "dependencies": [
-            "cffi",
-            "six"
-          ],
-          "is_direct": true,
-          "source": "PyNaCl_1_3_0_cp34_abi3_manylinux1_x86_64",
-          "version": "1.3.0"
-        },
-        "python-dateutil": {
-          "dependencies": [
-            "six"
-          ],
-          "is_direct": true,
-          "source": "python_dateutil_2_8_0_py2_py3_none_any",
-          "version": "2.8.0"
-        },
-        "pytz": {
-          "dependencies": [],
-          "is_direct": true,
-          "source": "pytz_2019_1_py2_py3_none_any",
-          "version": "2019.1"
-        },
-        "requests": {
-          "dependencies": [
-            "certifi",
-            "chardet",
-            "idna",
-            "urllib3"
-          ],
-          "is_direct": true,
-          "source": "requests_2_22_0_py2_py3_none_any",
-          "version": "2.22.0"
-        },
-        "requests-oauthlib": {
-          "dependencies": [
-            "oauthlib",
-            "requests"
-          ],
-          "is_direct": true,
-          "source": "requests_oauthlib_1_3_0_py2_py3_none_any",
-          "version": "1.3.0"
-        },
-        "setuptools": {
-          "dependencies": [],
-          "is_direct": false,
-          "source": "setuptools_41_2_0_py2_py3_none_any",
-          "version": "41.2.0"
-        },
-        "six": {
-          "dependencies": [],
-          "is_direct": true,
-          "source": "six_1_12_0_py2_py3_none_any",
-          "version": "1.12.0"
-        },
-        "sqlalchemy": {
-          "dependencies": [],
-          "is_direct": true,
-          "source": "SQLAlchemy_1_3_8_cp36_cp36m_linux_x86_64",
-          "version": "1.3.8"
-        },
-        "sqlparse": {
-          "dependencies": [],
-          "is_direct": true,
-          "source": "sqlparse_0_3_0_py2_py3_none_any",
-          "version": "0.3.0"
-        },
-        "urllib3": {
-          "dependencies": [],
-          "is_direct": true,
-          "source": "urllib3_1_25_3_py2_py3_none_any",
-          "version": "1.25.3"
-        },
-        "uwsgi": {
-          "dependencies": [],
-          "is_direct": true,
-          "source": "uWSGI_2_0_18_cp36_cp36m_linux_x86_64",
-          "version": "2.0.18"
-        },
-        "werkzeug": {
-          "dependencies": [],
-          "is_direct": true,
-          "source": "Werkzeug_0_15_5_py2_py3_none_any",
-          "version": "0.15.5"
-        },
-        "wtforms": {
-          "dependencies": [],
-          "is_direct": true,
-          "source": "WTForms_2_2_1_py2_py3_none_any",
-          "version": "2.2.1"
-        }
-      },
-      "sys_platform": "linux"
-    }
-  },
-  "local_wheels_package": "@hscloud//third_party/py/wheels",
-  "sources": {
-    "Click_7_0_py2_py3_none_any": {
-      "sha256": "2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13",
-      "url": "https://files.pythonhosted.org/packages/fa/37/45185cb5abbc30d7257104c434fe0b07e5a195a6847506c074527aa599ec/Click-7.0-py2.py3-none-any.whl"
-    },
-    "Django_2_2_3_py3_none_any": {
-      "sha256": "6e974d4b57e3b29e4882b244d40171d6a75202ab8d2402b8e8adbd182e25cf0c",
-      "url": "https://files.pythonhosted.org/packages/39/b0/2138c31bf13e17afc32277239da53e9dfcce27bac8cb68cf1c0123f1fdf5/Django-2.2.3-py3-none-any.whl"
-    },
-    "Flask_1_1_1_py2_py3_none_any": {
-      "sha256": "45eb5a6fd193d6cf7e0cf5d8a5b31f83d5faae0293695626f539a823e93b13f6",
-      "url": "https://files.pythonhosted.org/packages/9b/93/628509b8d5dc749656a9641f4caf13540e2cdec85276964ff8f43bbb1d3b/Flask-1.1.1-py2.py3-none-any.whl"
-    },
-    "Flask_Login_0_4_1_py2_py3_none_any": {
-      "file": "Flask_Login-0.4.1-py2.py3-none-any.whl"
-    },
-    "Flask_OAuthlib_0_9_5_py3_none_any": {
-      "file": "Flask_OAuthlib-0.9.5-py3-none-any.whl"
-    },
-    "Flask_SQLAlchemy_2_4_0_py2_py3_none_any": {
-      "sha256": "8631bbea987bc3eb0f72b1f691d47bd37ceb795e73b59ab48586d76d75a7c605",
-      "url": "https://files.pythonhosted.org/packages/08/ca/582442cad71504a1514a2f053006c8bb128844133d6076a4df17117545fa/Flask_SQLAlchemy-2.4.0-py2.py3-none-any.whl"
-    },
-    "Flask_WTF_0_14_2_py2_py3_none_any": {
-      "sha256": "d9a9e366b32dcbb98ef17228e76be15702cd2600675668bca23f63a7947fd5ac",
-      "url": "https://files.pythonhosted.org/packages/60/3a/58c629472d10539ae5167dc7c1fecfa95dd7d0b7864623931e3776438a24/Flask_WTF-0.14.2-py2.py3-none-any.whl"
-    },
-    "Jinja2_2_10_1_py2_py3_none_any": {
-      "sha256": "14dd6caf1527abb21f08f86c784eac40853ba93edb79552aa1e4b8aef1b61c7b",
-      "url": "https://files.pythonhosted.org/packages/1d/e7/fd8b501e7a6dfe492a433deb7b9d833d39ca74916fa8bc63dd1a4947a671/Jinja2-2.10.1-py2.py3-none-any.whl"
-    },
-    "MarkupSafe_1_1_1_cp36_cp36m_manylinux1_x86_64": {
-      "sha256": "717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e",
-      "url": "https://files.pythonhosted.org/packages/b2/5f/23e0023be6bb885d00ffbefad2942bc51a620328ee910f64abe5a8d18dd1/MarkupSafe-1.1.1-cp36-cp36m-manylinux1_x86_64.whl"
-    },
-    "PyNaCl_1_3_0_cp34_abi3_manylinux1_x86_64": {
-      "sha256": "aabb0c5232910a20eec8563503c153a8e78bbf5459490c49ab31f6adf3f3a415",
-      "url": "https://files.pythonhosted.org/packages/27/15/2cd0a203f318c2240b42cd9dd13c931ddd61067809fee3479f44f086103e/PyNaCl-1.3.0-cp34-abi3-manylinux1_x86_64.whl"
-    },
-    "SQLAlchemy_1_3_8_cp36_cp36m_linux_x86_64": {
-      "file": "SQLAlchemy-1.3.8-cp36-cp36m-linux_x86_64.whl"
-    },
-    "WTForms_2_2_1_py2_py3_none_any": {
-      "sha256": "e3ee092c827582c50877cdbd49e9ce6d2c5c1f6561f849b3b068c1b8029626f1",
-      "url": "https://files.pythonhosted.org/packages/9f/c8/dac5dce9908df1d9d48ec0e26e2a250839fa36ea2c602cc4f85ccfeb5c65/WTForms-2.2.1-py2.py3-none-any.whl"
-    },
-    "Werkzeug_0_15_5_py2_py3_none_any": {
-      "sha256": "87ae4e5b5366da2347eb3116c0e6c681a0e939a33b2805e2c0cbd282664932c4",
-      "url": "https://files.pythonhosted.org/packages/d1/ab/d3bed6b92042622d24decc7aadc8877badf18aeca1571045840ad4956d3f/Werkzeug-0.15.5-py2.py3-none-any.whl"
-    },
-    "arrow_0_14_5_py2_py3_none_any": {
-      "sha256": "a12de0124d812d15061ed36c7eb4a421fa1b95026a502a0b2062e9ea00fc4446",
-      "url": "https://files.pythonhosted.org/packages/4f/c6/32df2c68e02e2d6b4457223fa499634edabb2d4ff74f00087ffff49b4be4/arrow-0.14.5-py2.py3-none-any.whl"
-    },
-    "asn1crypto_0_24_0_py2_py3_none_any": {
-      "sha256": "2f1adbb7546ed199e3c90ef23ec95c5cf3585bac7d11fb7eb562a3fe89c64e87",
-      "url": "https://files.pythonhosted.org/packages/ea/cd/35485615f45f30a510576f1a56d1e0a7ad7bd8ab5ed7cdc600ef7cd06222/asn1crypto-0.24.0-py2.py3-none-any.whl"
-    },
-    "bcrypt_3_1_5_cp34_abi3_manylinux1_x86_64": {
-      "sha256": "efcaace6e2915434d84e865c44f0cfe34e802269378afbb39a4aa6381aaec78b",
-      "url": "https://files.pythonhosted.org/packages/31/4b/4057d0716e7170c29ff12e19791eb6037422620835e4a58a01d4790e56d1/bcrypt-3.1.5-cp34-abi3-manylinux1_x86_64.whl"
-    },
-    "blinker_1_4_py3_none_any": {
-      "file": "blinker-1.4-py3-none-any.whl"
-    },
-    "certifi_2019_6_16_py2_py3_none_any": {
-      "sha256": "046832c04d4e752f37383b628bc601a7ea7211496b4638f6514d0e5b9acc4939",
-      "url": "https://files.pythonhosted.org/packages/69/1b/b853c7a9d4f6a6d00749e94eb6f3a041e342a885b87340b79c1ef73e3a78/certifi-2019.6.16-py2.py3-none-any.whl"
-    },
-    "cffi_1_11_5_cp36_cp36m_manylinux1_x86_64": {
-      "sha256": "770f3782b31f50b68627e22f91cb182c48c47c02eb405fd689472aa7b7aa16dc",
-      "url": "https://files.pythonhosted.org/packages/6d/c0/47db8f624f3e4e2f3f27be03a93379d1ba16a1450a7b1aacfa0366e2c0dd/cffi-1.11.5-cp36-cp36m-manylinux1_x86_64.whl"
-    },
-    "chardet_3_0_4_py2_py3_none_any": {
-      "sha256": "fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691",
-      "url": "https://files.pythonhosted.org/packages/bc/a9/01ffebfb562e4274b6487b4bb1ddec7ca55ec7510b22e4c51f14098443b8/chardet-3.0.4-py2.py3-none-any.whl"
-    },
-    "cockroachdb_0_3_3_py3_none_any": {
-      "file": "cockroachdb-0.3.3-py3-none-any.whl"
-    },
-    "cryptography_2_4_2_cp34_abi3_manylinux1_x86_64": {
-      "sha256": "70596e90398574b77929cd87e1ac6e43edd0e29ba01e1365fed9c26bde295aa5",
-      "url": "https://files.pythonhosted.org/packages/60/c7/99b33c53cf3f20a97a4c4bfd3ab66dcc93d99da0a97cc9597aa36ae6bb62/cryptography-2.4.2-cp34-abi3-manylinux1_x86_64.whl"
-    },
-    "fabric_2_4_0_py2_py3_none_any": {
-      "sha256": "98538f2f3f63cf52497a8d0b24d18424ae83fe67ac7611225c72afb9e67f2cf6",
-      "url": "https://files.pythonhosted.org/packages/d9/e4/e6fa248c94ee5d45def54b609fcf70f39d0b7f7050f2d4405c5f156b5516/fabric-2.4.0-py2.py3-none-any.whl"
-    },
-    "future_0_17_1_py3_none_any": {
-      "file": "future-0.17.1-py3-none-any.whl"
-    },
-    "gevent_1_4_0_cp36_cp36m_manylinux1_x86_64": {
-      "sha256": "2711e69788ddb34c059a30186e05c55a6b611cb9e34ac343e69cf3264d42fe1c",
-      "url": "https://files.pythonhosted.org/packages/f2/ca/5b5962361ed832847b6b2f9a2d0452c8c2f29a93baef850bb8ad067c7bf9/gevent-1.4.0-cp36-cp36m-manylinux1_x86_64.whl"
-    },
-    "greenlet_0_4_15_cp36_cp36m_manylinux1_x86_64": {
-      "sha256": "23d12eacffa9d0f290c0fe0c4e81ba6d5f3a5b7ac3c30a5eaf0126bf4deda5c8",
-      "url": "https://files.pythonhosted.org/packages/bf/45/142141aa47e01a5779f0fa5a53b81f8379ce8f2b1cd13df7d2f1d751ae42/greenlet-0.4.15-cp36-cp36m-manylinux1_x86_64.whl"
-    },
-    "grpcio_1_22_0_cp36_cp36m_manylinux1_x86_64": {
-      "sha256": "561bca3b1bde6d6564306eb05848fd155136e9c3a25d2961129b1e2edba22fce",
-      "url": "https://files.pythonhosted.org/packages/f2/5d/b434403adb2db8853a97828d3d19f2032e79d630e0d11a8e95d243103a11/grpcio-1.22.0-cp36-cp36m-manylinux1_x86_64.whl"
-    },
-    "gunicorn_19_9_0_py2_py3_none_any": {
-      "sha256": "aa8e0b40b4157b36a5df5e599f45c9c76d6af43845ba3b3b0efe2c70473c2471",
-      "url": "https://files.pythonhosted.org/packages/8c/da/b8dd8deb741bff556db53902d4706774c8e1e67265f69528c14c003644e6/gunicorn-19.9.0-py2.py3-none-any.whl"
-    },
-    "idna_2_8_py2_py3_none_any": {
-      "sha256": "ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c",
-      "url": "https://files.pythonhosted.org/packages/14/2c/cd551d81dbe15200be1cf41cd03869a46fe7226e7450af7a6545bfc474c9/idna-2.8-py2.py3-none-any.whl"
-    },
-    "invoke_1_2_0_py3_none_any": {
-      "sha256": "4f4de934b15c2276caa4fbc5a3b8a61c0eb0b234f2be1780d2b793321995c2d6",
-      "url": "https://files.pythonhosted.org/packages/be/9f/8508712c9cad73ac0c8eeb2c3e51c9ef65136653dda2b512bde64109f023/invoke-1.2.0-py3-none-any.whl"
-    },
-    "itsdangerous_1_1_0_py2_py3_none_any": {
-      "sha256": "b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749",
-      "url": "https://files.pythonhosted.org/packages/76/ae/44b03b253d6fade317f32c24d100b3b35c2239807046a4c953c7b89fa49e/itsdangerous-1.1.0-py2.py3-none-any.whl"
-    },
-    "oauthlib_2_1_0_py2_py3_none_any": {
-      "sha256": "d883b36b21a6ad813953803edfa563b1b579d79ca758fe950d1bc9e8b326025b",
-      "url": "https://files.pythonhosted.org/packages/e6/d1/ddd9cfea3e736399b97ded5c2dd62d1322adef4a72d816f1ed1049d6a179/oauthlib-2.1.0-py2.py3-none-any.whl"
-    },
-    "paramiko_2_4_2_py2_py3_none_any": {
-      "sha256": "3c16b2bfb4c0d810b24c40155dbfd113c0521e7e6ee593d704e84b4c658a1f3b",
-      "url": "https://files.pythonhosted.org/packages/cf/ae/94e70d49044ccc234bfdba20114fa947d7ba6eb68a2e452d89b920e62227/paramiko-2.4.2-py2.py3-none-any.whl"
-    },
-    "protobuf_3_9_0_cp36_cp36m_manylinux1_x86_64": {
-      "sha256": "2ad566b7b7cdd8717c7af1825e19f09e8fef2787b77fcb979588944657679604",
-      "url": "https://files.pythonhosted.org/packages/dc/0e/e7cdff89745986c984ba58e6ff6541bc5c388dd9ab9d7d312b3b1532584a/protobuf-3.9.0-cp36-cp36m-manylinux1_x86_64.whl"
-    },
-    "psycopg2_2_7_7_cp36_cp36m_manylinux1_x86_64": {
-      "sha256": "ed7e0849337bd37d89f2c2b0216a0de863399ee5d363d31b1e5330a99044737b",
-      "url": "https://files.pythonhosted.org/packages/37/25/53e8398975aa3323de46a5cc2745aeb4c9db11352ca905d3a15c53b6a816/psycopg2-2.7.7-cp36-cp36m-manylinux1_x86_64.whl"
-    },
-    "pyasn1_0_4_5_py2_py3_none_any": {
-      "sha256": "da6b43a8c9ae93bc80e2739efb38cc776ba74a886e3e9318d65fe81a8b8a2c6e",
-      "url": "https://files.pythonhosted.org/packages/7b/7c/c9386b82a25115cccf1903441bba3cbadcfae7b678a20167347fa8ded34c/pyasn1-0.4.5-py2.py3-none-any.whl"
-    },
-    "pycparser_2_19_py2_py3_none_any": {
-      "file": "pycparser-2.19-py2.py3-none-any.whl"
-    },
-    "python_dateutil_2_8_0_py2_py3_none_any": {
-      "sha256": "7e6584c74aeed623791615e26efd690f29817a27c73085b78e4bad02493df2fb",
-      "url": "https://files.pythonhosted.org/packages/41/17/c62faccbfbd163c7f57f3844689e3a78bae1f403648a6afb1d0866d87fbb/python_dateutil-2.8.0-py2.py3-none-any.whl"
-    },
-    "pytz_2019_1_py2_py3_none_any": {
-      "sha256": "303879e36b721603cc54604edcac9d20401bdbe31e1e4fdee5b9f98d5d31dfda",
-      "url": "https://files.pythonhosted.org/packages/3d/73/fe30c2daaaa0713420d0382b16fbb761409f532c56bdcc514bf7b6262bb6/pytz-2019.1-py2.py3-none-any.whl"
-    },
-    "requests_2_22_0_py2_py3_none_any": {
-      "sha256": "9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31",
-      "url": "https://files.pythonhosted.org/packages/51/bd/23c926cd341ea6b7dd0b2a00aba99ae0f828be89d72b2190f27c11d4b7fb/requests-2.22.0-py2.py3-none-any.whl"
-    },
-    "requests_oauthlib_1_3_0_py2_py3_none_any": {
-      "sha256": "7f71572defaecd16372f9006f33c2ec8c077c3cfa6f5911a9a90202beb513f3d",
-      "url": "https://files.pythonhosted.org/packages/a3/12/b92740d845ab62ea4edf04d2f4164d82532b5a0b03836d4d4e71c6f3d379/requests_oauthlib-1.3.0-py2.py3-none-any.whl"
-    },
-    "setuptools_41_2_0_py2_py3_none_any": {
-      "sha256": "4380abcf2a4ffd1a5ba22d687c6d690dce83b2b51c70e9c6d09f7e8c7e8040dc",
-      "url": "https://files.pythonhosted.org/packages/b2/86/095d2f7829badc207c893dd4ac767e871f6cd547145df797ea26baea4e2e/setuptools-41.2.0-py2.py3-none-any.whl"
-    },
-    "six_1_12_0_py2_py3_none_any": {
-      "sha256": "3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c",
-      "url": "https://files.pythonhosted.org/packages/73/fb/00a976f728d0d1fecfe898238ce23f502a721c0ac0ecfedb80e0d88c64e9/six-1.12.0-py2.py3-none-any.whl"
-    },
-    "sqlparse_0_3_0_py2_py3_none_any": {
-      "sha256": "40afe6b8d4b1117e7dff5504d7a8ce07d9a1b15aeeade8a2d10f130a834f8177",
-      "url": "https://files.pythonhosted.org/packages/ef/53/900f7d2a54557c6a37886585a91336520e5539e3ae2423ff1102daf4f3a7/sqlparse-0.3.0-py2.py3-none-any.whl"
-    },
-    "uWSGI_2_0_18_cp36_cp36m_linux_x86_64": {
-      "file": "uWSGI-2.0.18-cp36-cp36m-linux_x86_64.whl"
-    },
-    "urllib3_1_25_3_py2_py3_none_any": {
-      "sha256": "b246607a25ac80bedac05c6f282e3cdaf3afb65420fd024ac94435cabe6e18d1",
-      "url": "https://files.pythonhosted.org/packages/e6/60/247f23a7121ae632d62811ba7f273d0e58972d75e58a94d329d51550a47d/urllib3-1.25.3-py2.py3-none-any.whl"
-    }
-  }
-}
\ No newline at end of file
diff --git a/third_party/py/requirements.txt b/third_party/py/requirements.txt
index 02ed586..eb3df74 100644
--- a/third_party/py/requirements.txt
+++ b/third_party/py/requirements.txt
@@ -1,3 +1,6 @@
+# grpcio and protobuf are installed directly via WORKSPACE
+# do NOT add them there
+# depending on a py_grpc_library output will pull in the required deps
 arrow==0.14.5
 asn1crypto==0.24.0
 bcrypt==3.1.5
@@ -18,7 +21,6 @@
 future==0.17.1
 gevent==1.4.0
 greenlet==0.4.15
-grpcio==1.22.0
 gunicorn==19.9.0
 idna==2.8
 invoke==1.2.0
@@ -27,7 +29,6 @@
 MarkupSafe==1.1.1
 oauthlib==2.1.0
 paramiko==2.4.2
-protobuf==3.9.0
 psycopg2==2.7.7
 pyasn1==0.4.5
 pycparser==2.19
diff --git a/third_party/py/wheels/BUILD b/third_party/py/wheels/BUILD
deleted file mode 100644
index 1b09257..0000000
--- a/third_party/py/wheels/BUILD
+++ /dev/null
@@ -1 +0,0 @@
-# This is a generated file which may be overwritten with a custom BUILD file
\ No newline at end of file
diff --git a/third_party/py/wheels/Flask_Login-0.4.1-py2.py3-none-any.whl b/third_party/py/wheels/Flask_Login-0.4.1-py2.py3-none-any.whl
deleted file mode 100644
index f200a54..0000000
--- a/third_party/py/wheels/Flask_Login-0.4.1-py2.py3-none-any.whl
+++ /dev/null
Binary files differ
diff --git a/third_party/py/wheels/Flask_OAuthlib-0.9.5-py3-none-any.whl b/third_party/py/wheels/Flask_OAuthlib-0.9.5-py3-none-any.whl
deleted file mode 100644
index 30fba3d..0000000
--- a/third_party/py/wheels/Flask_OAuthlib-0.9.5-py3-none-any.whl
+++ /dev/null
Binary files differ
diff --git a/third_party/py/wheels/SQLAlchemy-1.3.8-cp36-cp36m-linux_x86_64.whl b/third_party/py/wheels/SQLAlchemy-1.3.8-cp36-cp36m-linux_x86_64.whl
deleted file mode 100644
index b54494b..0000000
--- a/third_party/py/wheels/SQLAlchemy-1.3.8-cp36-cp36m-linux_x86_64.whl
+++ /dev/null
Binary files differ
diff --git a/third_party/py/wheels/blinker-1.4-py3-none-any.whl b/third_party/py/wheels/blinker-1.4-py3-none-any.whl
deleted file mode 100644
index b2d4d59..0000000
--- a/third_party/py/wheels/blinker-1.4-py3-none-any.whl
+++ /dev/null
Binary files differ
diff --git a/third_party/py/wheels/cockroachdb-0.3.3-py3-none-any.whl b/third_party/py/wheels/cockroachdb-0.3.3-py3-none-any.whl
deleted file mode 100644
index f40f02b..0000000
--- a/third_party/py/wheels/cockroachdb-0.3.3-py3-none-any.whl
+++ /dev/null
Binary files differ
diff --git a/third_party/py/wheels/future-0.17.1-py3-none-any.whl b/third_party/py/wheels/future-0.17.1-py3-none-any.whl
deleted file mode 100644
index 77f89e3..0000000
--- a/third_party/py/wheels/future-0.17.1-py3-none-any.whl
+++ /dev/null
Binary files differ
diff --git a/third_party/py/wheels/pycparser-2.19-py2.py3-none-any.whl b/third_party/py/wheels/pycparser-2.19-py2.py3-none-any.whl
deleted file mode 100644
index f00822f..0000000
--- a/third_party/py/wheels/pycparser-2.19-py2.py3-none-any.whl
+++ /dev/null
Binary files differ
diff --git a/third_party/py/wheels/uWSGI-2.0.18-cp36-cp36m-linux_x86_64.whl b/third_party/py/wheels/uWSGI-2.0.18-cp36-cp36m-linux_x86_64.whl
deleted file mode 100644
index 1bf3680..0000000
--- a/third_party/py/wheels/uWSGI-2.0.18-cp36-cp36m-linux_x86_64.whl
+++ /dev/null
Binary files differ