Source code for colab_host.colab_host

import subprocess
from pyngrok import ngrok
from git import Repo
import re
import os
import shutil
from pathlib import Path


[docs]class Host: """Base class for hosting any python application. Given `port` number it will expose the port to internet. Given `requirements` will install them using `pip install`. Given `git_url` it will clone the repo for you. Parameters: port : int, optional requirements : List[str] or str, optional List[str]: list of package requirements for hosting. str: requirements file path to install requirements from. git_url : str, optional """ def __init__( self, port: int = 1000, requirements: list or str = None, git_url: str = None ): super().__init__() if isinstance(git_url, str): self._clone_repo(git_url) self._install_requirements(requirements) self.port = port self._start_tunnel() def _clone_repo(self, git_url) -> Repo: folder_name = re.search(r"[^/]+$", git_url).group().replace(".git", "") folder = Path(folder_name) if folder.exists() and folder.is_dir(): shutil.rmtree(folder) repo = Repo.clone_from(git_url, folder) self.repo = repo os.chdir(self.repo.working_dir) def _install_requirements(self, requirements: list or str): subprocess.run(f"pip install --upgrade pip".split(), stdout=subprocess.PIPE) if not isinstance(requirements, (str, list)): return if isinstance(requirements, str): requirements_file = f"{self.repo.working_dir}/{requirements}" subprocess.run( ["pip", "install", "-r", requirements_file], stdout=subprocess.PIPE ) return for requirement in requirements: subprocess.run(f"pip install {requirement}".split(), stdout=subprocess.PIPE) def _start_tunnel(self): active_tunnels = ngrok.get_tunnels() for tunnel in active_tunnels: public_url = tunnel.public_url ngrok.disconnect(public_url) url = ngrok.connect(port=self.port, options={"bind_tls": True}) print(f"Hosted Server can be accessed on: {url}")
[docs]class SimpleHttpServer(Host): """Class to expose simple file server application. Parameters: port : int, optional """ def __init__(self, port: int = 1000): super().__init__(port) self._start_server() def _start_server(self): subprocess.run( f"python -m http.server {self.port}".split(), stdout=subprocess.PIPE )
[docs]class JupyterNotebook(Host): """Class to expose Jupyter Notebook IDE on browser. Parameters: port : int, optional requirements : List[str], optional Defaults to `["notebook"]` and you can include other packages to include with this. For example notebook extension, theme, etc """ def __init__(self, port: int = 1000, requirements: list = ["notebook"]): super().__init__(port, requirements) self._start_server() def _start_server(self): subprocess.run( f"python -m jupyter notebook --allow-root --ip=0.0.0.0 --port {self.port}".split(), stdout=subprocess.PIPE, )
[docs]class JupyterLab(Host): """Class to expose Jupyter Lab IDE on browser. Parameters: port : int, optional requirements : List[str], optional Defaults to `["jupyterlab"]` and you can include other packages to include with this. For example notebook extension, theme, etc """ def __init__(self, port: int = 1000, requirements: list = ["jupyterlab"]): super().__init__(port, requirements) self._start_server() def _start_server(self): subprocess.run( f"python -m jupyter lab --allow-root --ip=0.0.0.0 --port {self.port}".split(), stdout=subprocess.PIPE, )
[docs]class FlaskApp(Host): """Class to expose python Flask or Gunicorn application. Parameters: port : int, optional app : str, optional Definition of your python gunicorn app. (Defaults to `"main:app"`). git_url : str, optional Git URL to clone your repo containing application. (Defaults to `"https://github.com/PuneethaPai/colab_host_flask_demo"`). requirements_file: str, optional Name of file in repo `git_url` containing requirements for hosting the application. (Defaults to `"requirements.txt"`). """ def __init__( self, port: int = 1000, app="main:app", git_url="https://github.com/PuneethaPai/colab_host_flask_demo", requirements_file: str = "requirements.txt", ): self.port = port self.app = app super().__init__(port, requirements_file, git_url) self._start_server() def _start_server(self): subprocess.run( f"gunicorn --bind 0.0.0.0:{self.port} {self.app}".split(), stdout=subprocess.PIPE, )
[docs]class UvicornApp(Host): """Class to expose python FastApi or Uvicorn application. Parameters: port : int, optional app : str, optional Definition of your python gunicorn app. (Defaults to `"main:app"`). git_url : str, optional Git URL to clone your repo containing application. (Defaults to `"https://github.com/PuneethaPai/colab_host_uvicorn_demo"`). requirements_file: str, optional Name of file in repo `git_url` containing requirements for hosting the application. (Defaults to `"requirements.txt"`). """ def __init__( self, port: int = 1000, app="main:app", git_url="https://github.com/PuneethaPai/colab_host_flask_demo", requirements_file: str = "requirements.txt", ): self.port = port self.app = app super().__init__(port, requirements_file, git_url) self._start_server() def _start_server(self): subprocess.run( f"uvicorn --host 0.0.0.0 --port {self.port} {self.app}".split(), stdout=subprocess.PIPE, )