Repository: OpenMined/PySyft

Issue:
Rename load_lib to load
## Description
- [x] Rename `sy.load_lib` to `sy.load`.
Leave old method but pass through to new method and add DeprecationWarning like here:
https://github.com/OpenMined/PySyft/blob/fb4f99028338d4e59fb702f1f6ec60f1e16bc660/src/syft/ast/klass.py#L322

- [x] Add test to `api/deprecated_test.py`
- [x] Look into auto loading libraries using a post import hook:
https://stackoverflow.com/questions/40623889/post-import-hooks-in-python-3
https://github.com/GrahamDumpleton/wrapt
https://www.youtube.com/watch?v=u7oj-ghfhUk
- [x] Update notebooks

## Definition of Done
`sy.load_lib` is deprecated but still functional and replaced with `sy.load`




Discussion:
Hi @madhavajay can I work on this?
@avinsit123 could you also open a PR in [SyMPC](https://github.com/OpenMined/SyMPC/blob/main/src/sympc/__init__.py#L23) for changing the name?
Sure @gmuraru I will do that after completing the PR here if thats fine!!
Hello @avinsit123 !

Open a PR and lets talk directly on that. :100:

Resolving patch:
diff --git a/src/syft/__init__.py b/src/syft/__init__.py
--- a/src/syft/__init__.py
+++ b/src/syft/__init__.py
@@ -72,7 +72,7 @@
 
 # Convenience Objects
 from syft.lib import lib_ast  # noqa: F401
-from syft.lib import load_lib  # noqa: F401
+from syft.lib import load  # noqa: F401
 from syft.lib.torch.module import Module  # noqa: F401
 
 # syft relative
diff --git a/src/syft/lib/__init__.py b/src/syft/lib/__init__.py
--- a/src/syft/lib/__init__.py
+++ b/src/syft/lib/__init__.py
@@ -5,6 +5,7 @@
 from typing import Any as TypeAny
 from typing import Dict as TypeDict
 from typing import Optional
+import warnings
 
 # third party
 from packaging import version
@@ -17,6 +18,7 @@
 from ..lib.torchvision import create_torchvision_ast
 from ..logger import critical
 from ..logger import traceback_and_raise
+from ..logger import warning
 from .misc import create_union_ast
 
 
@@ -25,6 +27,16 @@ class VendorLibraryImportException(Exception):
 
 
 def vendor_requirements_available(vendor_requirements: TypeDict[str, TypeAny]) -> bool:
+    """
+    Check whether torch or python version is supported
+
+    Args:
+        vendor_requirements: dictionary containing version of python or torch to be supported
+
+    Returns:
+        True if system supports all vendor requirements
+
+    """
     # see if python version is supported
     if "python" in vendor_requirements:
         python_reqs = vendor_requirements["python"]
@@ -80,6 +92,13 @@ def vendor_requirements_available(vendor_requirements: TypeDict[str, TypeAny]) -
 
 
 def _load_lib(lib: str, options: TypeDict[str, TypeAny] = {}) -> None:
+    """
+    Load and Update Node with given library module
+
+    Args:
+        lib: name of library to load and update Node with
+        options: external requirements for loading library successfully
+    """
     _ = importlib.import_module(lib)
     vendor_ast = importlib.import_module(f"syft.lib.{lib}")
     PACKAGE_SUPPORT = getattr(vendor_ast, "PACKAGE_SUPPORT", None)
@@ -99,7 +118,14 @@ def _load_lib(lib: str, options: TypeDict[str, TypeAny] = {}) -> None:
             lib_ast.loaded_lib_constructors[lib] = update_ast
 
 
-def load_lib(lib: str, options: TypeDict[str, TypeAny] = {}) -> None:
+def load(lib: str, options: TypeDict[str, TypeAny] = {}) -> None:
+    """
+    Load and Update Node with given library module
+
+    Args:
+        lib: name of library to load and update Node with
+        options: external requirements for loading library successfully
+    """
     try:
         _load_lib(lib=lib, options=options)
     except VendorLibraryImportException as e:
@@ -108,8 +134,34 @@ def load_lib(lib: str, options: TypeDict[str, TypeAny] = {}) -> None:
         critical(f"Unable to load package support for: {lib}. {e}")
 
 
+def load_lib(lib: str, options: TypeDict[str, TypeAny] = {}) -> None:
+    """
+    Load and Update Node with given library module
+    load_lib() is deprecated please use load() in the future
+
+    Args:
+        lib: name of library to load and update Node with
+        options: external requirements for loading library successfully
+
+    """
+    msg = "load_lib() is deprecated please use load() in the future"
+    warning(msg, print=True)
+    warnings.warn(msg, DeprecationWarning)
+    load(lib=lib, options=options)
+
+
 # now we need to load the relevant frameworks onto the node
 def create_lib_ast(client: Optional[Any] = None) -> Globals:
+    """
+    Create AST and load the relevant frameworks onto the node
+
+    Args:
+        client: VM client onto whom the frameworks need to be loaded
+
+    Returns:
+        AST for client of type Globals
+
+    """
     python_ast = create_python_ast(client=client)
     torch_ast = create_torch_ast(client=client)
     torchvision_ast = create_torchvision_ast(client=client)


Test patch:
diff --git a/.github/workflows/pr_tests.yml b/.github/workflows/pr_tests.yml
--- a/.github/workflows/pr_tests.yml
+++ b/.github/workflows/pr_tests.yml
@@ -169,6 +169,7 @@ jobs:
 
       - name: Run supported library tests
         run: |
+          pip install -r requirements.libs.deps.txt
           pip list
           pytest -m libs --co
           pytest -m libs -n auto -k "not tenseal" --suppress-no-test-exit-code
diff --git a/tests/syft/api/deprecated_test.py b/tests/syft/api/deprecated_test.py
--- a/tests/syft/api/deprecated_test.py
+++ b/tests/syft/api/deprecated_test.py
@@ -4,6 +4,7 @@
 
 # syft absolute
 import syft as sy
+from syft.lib import load_lib
 
 
 def test_searchable_pointable() -> None:
@@ -21,3 +22,8 @@ def test_searchable_pointable() -> None:
     with pytest.deprecated_call():
         x_ptr.searchable = False
         assert x_ptr.searchable is False
+
+
+def test_load_lib_deprecated() -> None:
+    with pytest.deprecated_call():
+        assert load_lib("tenseal") is None
diff --git a/tests/syft/lib/opacus/opacus_test.py b/tests/syft/lib/opacus/opacus_test.py
--- a/tests/syft/lib/opacus/opacus_test.py
+++ b/tests/syft/lib/opacus/opacus_test.py
@@ -7,7 +7,7 @@
 
 @pytest.mark.vendor(lib="opacus")
 def test_remote_engine_simple() -> None:
-    sy.load_lib("opacus")
+    sy.load("opacus")
 
     data_owner = sy.VirtualMachine().get_root_client()
     remote_opacus = data_owner.opacus
diff --git a/tests/syft/lib/psi/psi_test.py b/tests/syft/lib/psi/psi_test.py
--- a/tests/syft/lib/psi/psi_test.py
+++ b/tests/syft/lib/psi/psi_test.py
@@ -13,15 +13,15 @@ def test_psi(loadlib_before_client: bool, reveal_intersection: bool) -> None:
     # third party
     import openmined_psi as psi
 
-    # it should work when call load_lib before or after create clients
+    # it should work when call load before or after create clients
     if loadlib_before_client:
-        sy.load_lib("openmined_psi")
+        sy.load("openmined_psi")
         server_vm = sy.VirtualMachine().get_root_client()
         client_vm = sy.VirtualMachine().get_root_client()
     else:
         server_vm = sy.VirtualMachine().get_root_client()
         client_vm = sy.VirtualMachine().get_root_client()
-        sy.load_lib("openmined_psi")
+        sy.load("openmined_psi")
 
     # server send reveal_intersection
     s_reveal_intersection = reveal_intersection
diff --git a/tests/syft/lib/pydp/client_pydp_test.py b/tests/syft/lib/pydp/client_pydp_test.py
--- a/tests/syft/lib/pydp/client_pydp_test.py
+++ b/tests/syft/lib/pydp/client_pydp_test.py
@@ -7,7 +7,7 @@
 
 @pytest.mark.vendor(lib="pydp")
 def test_pydp() -> None:
-    sy.load_lib("pydp")
+    sy.load("pydp")
     bob = sy.VirtualMachine(name="Bob")
     client = bob.get_root_client()
     x_ptr = client.pydp.algorithms.laplacian.BoundedMean(1, 1, 50)
@@ -23,7 +23,7 @@ def test_pydp() -> None:
 
 @pytest.mark.vendor(lib="pydp")
 def test_pydp_functions() -> None:
-    sy.load_lib("pydp")
+    sy.load("pydp")
     bob = sy.VirtualMachine(name="Bob")
     client = bob.get_root_client()
     x_ptr = client.pydp.algorithms.laplacian.BoundedMean(1, 1, 50)
diff --git a/tests/syft/lib/sympc/sympc_test.py b/tests/syft/lib/sympc/sympc_test.py
--- a/tests/syft/lib/sympc/sympc_test.py
+++ b/tests/syft/lib/sympc/sympc_test.py
@@ -19,7 +19,7 @@ def test_load_sympc() -> None:
     from sympc.session import SessionManager
     from sympc.tensor import MPCTensor
 
-    sy.load_lib("sympc")
+    sy.load("sympc")
 
     session = Session(parties=[alice_client, bob_client])
     SessionManager.setup_mpc(session)
diff --git a/tests/syft/lib/tenseal/duet_test.py b/tests/syft/lib/tenseal/duet_test.py
--- a/tests/syft/lib/tenseal/duet_test.py
+++ b/tests/syft/lib/tenseal/duet_test.py
@@ -20,7 +20,7 @@
 from ...grid.duet.signaling_server_test import run
 
 ts = pytest.importorskip("tenseal")
-sy.load_lib("tenseal")
+sy.load("tenseal")
 
 set_start_method("spawn", force=True)
 PORT = 21000
@@ -48,7 +48,7 @@ def do(ct_size: int, batch_size: int) -> None:
     # syft absolute
     import syft as sy
 
-    sy.load_lib("tenseal")
+    sy.load("tenseal")
     sy.logger.add(sys.stderr, "ERROR")
 
     duet = sy.launch_duet(loopback=True, network_url=f"http://127.0.0.1:{PORT}/")
@@ -79,7 +79,7 @@ def ds(ct_size: int, batch_size: int) -> None:
     # syft absolute
     import syft as sy
 
-    sy.load_lib("tenseal")
+    sy.load("tenseal")
     sy.logger.add(sys.stderr, "ERROR")
 
     duet = sy.join_duet(loopback=True, network_url=f"http://127.0.0.1:{PORT}/")
diff --git a/tests/syft/lib/tenseal/tenseal_bfvvector_test.py b/tests/syft/lib/tenseal/tenseal_bfvvector_test.py
--- a/tests/syft/lib/tenseal/tenseal_bfvvector_test.py
+++ b/tests/syft/lib/tenseal/tenseal_bfvvector_test.py
@@ -11,7 +11,7 @@
 from .utils_test import decrypt
 
 ts = pytest.importorskip("tenseal")
-sy.load_lib("tenseal")
+sy.load("tenseal")
 
 
 @pytest.fixture(scope="function")
diff --git a/tests/syft/lib/tenseal/tenseal_ckkstensor_test.py b/tests/syft/lib/tenseal/tenseal_ckkstensor_test.py
--- a/tests/syft/lib/tenseal/tenseal_ckkstensor_test.py
+++ b/tests/syft/lib/tenseal/tenseal_ckkstensor_test.py
@@ -11,7 +11,7 @@
 from .utils_test import decrypt
 
 ts = pytest.importorskip("tenseal")
-sy.load_lib("tenseal")
+sy.load("tenseal")
 
 
 def _almost_equal(vec1: Any, vec2: Any, precision_pow_ten: int = 1) -> None:
diff --git a/tests/syft/lib/tenseal/tenseal_ckksvector_test.py b/tests/syft/lib/tenseal/tenseal_ckksvector_test.py
--- a/tests/syft/lib/tenseal/tenseal_ckksvector_test.py
+++ b/tests/syft/lib/tenseal/tenseal_ckksvector_test.py
@@ -12,7 +12,7 @@
 from .utils_test import decrypt
 
 ts = pytest.importorskip("tenseal")
-sy.load_lib("tenseal")
+sy.load("tenseal")
 
 
 def _almost_equal(vec1: Sequence, vec2: Sequence, precision_pow_ten: int = 1) -> None:
diff --git a/tests/syft/lib/tenseal/tenseal_context_test.py b/tests/syft/lib/tenseal/tenseal_context_test.py
--- a/tests/syft/lib/tenseal/tenseal_context_test.py
+++ b/tests/syft/lib/tenseal/tenseal_context_test.py
@@ -8,7 +8,7 @@
 import syft as sy
 
 ts = pytest.importorskip("tenseal")
-sy.load_lib("tenseal")
+sy.load("tenseal")
 
 
 @pytest.fixture(scope="function")