Repository: OpenMined/PySyft

Issue:
GSOD - Finish first two DO Notebooks
## Description
Awesome work on `quickstart` and the first two notebooks.

I think we should finish these up end to end and then once theyre mergable we can plan out the next few.

### Notebooks
- [x] Finish DO Create Domain and Upload Flow
- [x] rename files to be 00, 01, use hyphens and lowercase, remove redundant text like Data Owner
- [x] Create breadcrum and link top of Notebook to Install Wizard
- [x] Remove utils import from Upload notebook
- [x] Update README.md with links to published docs
- [x] Update HAGrid to download files and folders based off dev
- [x] Add relative path downloads to quickstart
- [x] Deploy notebook should use port 8081 or 9082 (just conventions we use in other places)
- [x] Add --silent to hagrid launch cell
- [x] Change hagrid check cell to use localhost:8081 (or 9082)
- [x] Change login to use no url but to include port=8081 (or 9082)
- [x] Link Notebooks in Sequence at the bottom of each tutorial
- [x] Move `hagrid quickstart` command to the top right of RST Docs

### HAGrid
```
$ hagrid quickstart data-owner
# downloads all files in dev branch data-owner
# and launches the 0th notebook
$ hagrid quickstart data-owner/00-deploy-domain 
# downloads just that notebook
```

- [x] Quickstart download overwrite prompt should include (all option) (y/n/a)
- [x] Add repo and branch/tag override to quickstart

```
$ hagrid quickstart data-owner/00-deploy-domain --repo=madhavajay/PySyft --branch=mybranch
$ hagrid quickstart data-owner/00-deploy-domain --repo=madhavajay/PySyft --commit=c75d98c3543954bfc8d1386205fbba1855f72b95
# downloads from those repo and or commit / branches where the default is `openmined/PySyft` and `dev`
```

- [x] hagrid disable jupyter extension on install
```
$ jupyter labextension disable @jupyterlab/cell-toolbar-extension
```

### Linting and Testing
- [ ] Make sure the notebooks run
- [x] Keep an eye out for formatting of code in cells
- [x] remove excess spacing on headings
- [x] Use normal font size for main text and custom headings
- [x] Proof read spelling and punctuation
- [x] Check for consistency



Discussion:
@abhiwalia15 and @ShubhamPalriwala can you comment on this issue so I can assign you both?
Hey @madhavajay, I would like to start with the Notebooks. Please assign this task to me; thanks!!
Yep, on it with @abhiwalia15 
> Hey @madhavajay, I would like to start with the Notebooks. Please assign this task to me; thanks!!

Hello @madhavajay, can you please assign this to me so I can tickmark the tasks I am completing?

Resolving patch:
diff --git a/packages/hagrid/hagrid/cli.py b/packages/hagrid/hagrid/cli.py
--- a/packages/hagrid/hagrid/cli.py
+++ b/packages/hagrid/hagrid/cli.py
@@ -13,12 +13,14 @@
 from typing import Any
 from typing import Callable
 from typing import Dict as TypeDict
+from typing import List
 from typing import List as TypeList
 from typing import Optional
 from typing import Tuple
 from typing import Tuple as TypeTuple
 from typing import Union
 from typing import cast
+from urllib.parse import urlparse
 
 # third party
 import click
@@ -2499,6 +2501,20 @@ def version() -> None:
     is_flag=True,
     help="CI Test Mode, don't hang on Jupyter",
 )
+@click.option(
+    "--repo",
+    default=arg_cache.repo,
+    help="Choose a repo to fetch the notebook from or just use OpenMined/PySyft",
+)
+@click.option(
+    "--branch",
+    default=DEFAULT_BRANCH,
+    help="Choose a branch to fetch from or just use dev",
+)
+@click.option(
+    "--commit",
+    help="Choose a specific commit to fetch the notebook from",
+)
 def quickstart_cli(
     url: Optional[str] = None,
     syft: str = "latest",
@@ -2506,6 +2522,9 @@ def quickstart_cli(
     quiet: bool = False,
     pre: bool = False,
     test: bool = False,
+    repo: str = arg_cache.repo,
+    branch: str = DEFAULT_BRANCH,
+    commit: Optional[str] = None,
     python: Optional[str] = None,
 ) -> None:
     try:
@@ -2532,9 +2551,32 @@ def quickstart_cli(
             )
 
         if url:
-            file_path, _ = quickstart_download_notebook(
-                url=url, directory=directory, reset=reset
-            )
+            allowed_schemes_as_url = ["http", "https"]
+            url_scheme = urlparse(url).scheme
+
+            if url_scheme not in allowed_schemes_as_url:
+                notebooks = get_urls_from_dir(
+                    repo=repo, branch=branch, commit=commit, url=url
+                )
+                overwrite_all_notebooks = False
+                if not reset:
+                    overwrite_all_notebooks = click.confirm(
+                        text=f"You have {len(notebooks)} conflicting notebooks. Would you like to overwrite them all?",
+                        default=False,
+                    )
+
+                for notebook_url in notebooks:
+                    file_path, _ = quickstart_download_notebook(
+                        url=notebook_url,
+                        directory=directory + "/" + url + "/",
+                        reset=reset,
+                        overwrite_all_notebooks=overwrite_all_notebooks,
+                    )
+
+            else:
+                file_path, _ = quickstart_download_notebook(
+                    url=url, directory=directory, reset=reset
+                )
         else:
             file_path = add_intro_notebook(directory=directory, reset=reset)
 
@@ -2562,6 +2604,12 @@ def quickstart_cli(
                     sys.exit(1)
                 print(f"Jupyter exists at: {jupyter_path}. CI Test mode exiting.")
                 sys.exit(0)
+
+            disable_toolbar_extension = f"{jupyter_binary} labextension disable @jupyterlab/cell-toolbar-extension"
+
+            subprocess.run(  # nosec
+                disable_toolbar_extension.split(" "), cwd=directory, env=environ
+            )
             proc = subprocess.Popen(  # nosec
                 cmd.split(" "),
                 cwd=directory,
@@ -2631,6 +2679,53 @@ def quickstart_setup(
         raise e
 
 
+def get_urls_from_dir(
+    repo: str,
+    branch: str,
+    commit: Optional[str],
+    url: str,
+) -> List[str]:
+    notebooks = []
+    if commit is not None:
+        gh_api_call = (
+            "https://api.github.com/repos/"
+            + repo
+            + "/git/trees/"
+            + commit
+            + "?recursive=1"
+        )
+    else:
+        gh_api_call = (
+            "https://api.github.com/repos/"
+            + repo
+            + "/git/trees/"
+            + branch
+            + "?recursive=1"
+        )
+    r = requests.get(gh_api_call)
+    if r.status_code != 200:
+        print(
+            f"Failed to fetch notebook from: {gh_api_call}.\nPlease try again with the correct parameters!"
+        )
+        sys.exit(1)
+
+    res = r.json()
+
+    for file in res["tree"]:
+        if file["path"].startswith("notebooks/quickstart/" + url):
+            if file["path"].endswith(".ipynb"):
+                temp_url = (
+                    "https://raw.githubusercontent.com/"
+                    + repo
+                    + "/"
+                    + branch
+                    + "/"
+                    + file["path"]
+                )
+                notebooks.append(temp_url)
+    return notebooks
+
+
 def add_intro_notebook(directory: str, reset: bool = False) -> str:
     files = os.listdir(directory)
     try:
diff --git a/packages/hagrid/hagrid/quickstart_ui.py b/packages/hagrid/hagrid/quickstart_ui.py
--- a/packages/hagrid/hagrid/quickstart_ui.py
+++ b/packages/hagrid/hagrid/quickstart_ui.py
@@ -15,13 +15,15 @@
 
 
 def quickstart_download_notebook(
-    url: str, directory: str, reset: bool = False
+    url: str, directory: str, reset: bool = False, overwrite_all_notebooks: bool = False
 ) -> Tuple[str, bool]:
     os.makedirs(directory, exist_ok=True)
     file_name = os.path.basename(url).replace("%20", "_")
     file_path = os.path.abspath(directory + file_name)
 
     file_exists = os.path.isfile(file_path)
+    if overwrite_all_notebooks:
+        reset = True
 
     if file_exists and not reset:
         reset = click.confirm(


Test patch: