diff --git a/instill/helpers/Dockerfile b/instill/helpers/Dockerfile index 75bb82a..2b7fc83 100644 --- a/instill/helpers/Dockerfile +++ b/instill/helpers/Dockerfile @@ -7,6 +7,11 @@ FROM rayproject/ray:${RAY_VERSION}-py${PYTHON_VERSION}${CUDA_SUFFIX}${TARGET_ARC RUN sudo apt-get update && sudo apt-get install curl -y +ARG SYSTEM_PACKAGES +RUN for package in ${SYSTEM_PACKAGES}; do \ + sudo apt-get install $package; \ + done; + ARG PACKAGES RUN for package in ${PACKAGES}; do \ pip install --default-timeout=1000 --no-cache-dir $package; \ diff --git a/instill/helpers/build.py b/instill/helpers/build.py index 1b2a618..7985139 100644 --- a/instill/helpers/build.py +++ b/instill/helpers/build.py @@ -11,15 +11,34 @@ import instill from instill.helpers.const import DEFAULT_DEPENDENCIES +from instill.helpers.errors import ModelConfigException from instill.utils.logger import Logger -if __name__ == "__main__": - Logger.i("[Instill Builder] Setup docker...") + +def config_check_required_fields(c): + if "build" not in c or c["build"] is None: + raise ModelConfigException("build") + if "gpu" not in c["build"] or c["build"]["gpu"] is None: + raise ModelConfigException("gpu") + if "python_version" not in c["build"] or c["build"]["python_version"] is None: + raise ModelConfigException("python_version") + if "repo" not in c or c["repo"] is None: + raise ModelConfigException("repo") + + +def build_image(): if platform.machine() in ("i386", "AMD64", "x86_64"): default_platform = "amd64" else: default_platform = platform.machine() parser = argparse.ArgumentParser() + parser.add_argument( + "-t", + "--tag", + help="tag for the model image", + default="", + required=False, + ) parser.add_argument( "--no-cache", help="build the image without cache", @@ -34,21 +53,18 @@ required=False, ) + args = parser.parse_args() try: - args = parser.parse_args() - Logger.i("[Instill Builder] Loading config file...") with open("instill.yaml", "r", encoding="utf8") as f: Logger.i("[Instill Builder] Parsing config file...") config = yaml.safe_load(f) + config_check_required_fields(config) + build = config["build"] repo = config["repo"] - tag = ( - config["tag"] - if config["tag"] is not None and config["tag"] != "" - else hashlib.sha256().hexdigest() - ) + tag = args.tag if args.tag != "" else hashlib.sha256().hexdigest() python_version = build["python_version"].replace(".", "") ray_version = ray.__version__ @@ -56,8 +72,13 @@ cuda_suffix = "" if not build["gpu"] else "-cu121" + system_str = "" + if "system_packages" in build and not build["system_packages"] is None: + for p in build["system_packages"]: + system_str += p + " " + packages_str = "" - if not build["python_packages"] is None: + if "python_packages" in build and not build["python_packages"] is None: for p in build["python_packages"]: packages_str += p + " " for p in DEFAULT_DEPENDENCIES: @@ -90,6 +111,8 @@ f"CUDA_SUFFIX={cuda_suffix}", "--build-arg", f"PACKAGES={packages_str}", + "--build-arg", + f"SYSTEM_PACKAGES={system_str}", "--platform", f"linux/{args.target_arch}", "-t", @@ -104,10 +127,14 @@ check=True, ) Logger.i(f"[Instill Builder] {repo}:{tag} built") - except subprocess.CalledProcessError as e: + except subprocess.CalledProcessError: Logger.e("[Instill Builder] Build failed") except Exception as e: Logger.e("[Instill Builder] Prepare failed") Logger.e(e) finally: Logger.i("[Instill Builder] Done") + + +if __name__ == "__main__": + build_image() diff --git a/instill/helpers/errors.py b/instill/helpers/errors.py index b937efb..03023bc 100644 --- a/instill/helpers/errors.py +++ b/instill/helpers/errors.py @@ -6,3 +6,13 @@ def __str__(self) -> str: class ModelVramException(Exception): def __str__(self) -> str: return "model projected vram usage is more than the GPU can handle" + + +class ModelConfigException(Exception): + def __init__(self, field): + self.field = field + + def __str__( + self, + ) -> str: + return f"model config file `instill.yaml` is missing {self.field} field" diff --git a/instill/helpers/push.py b/instill/helpers/push.py index de49b6e..4cc0166 100644 --- a/instill/helpers/push.py +++ b/instill/helpers/push.py @@ -5,9 +5,8 @@ from instill.utils.logger import Logger -if __name__ == "__main__": - Logger.i("[Instill Builder] Setup docker...") +def push_image(): parser = argparse.ArgumentParser() parser.add_argument( "-u", @@ -16,6 +15,12 @@ default="docker.io", required=False, ) + parser.add_argument( + "-t", + "--tag", + help="tag for the model image", + required=True, + ) try: args = parser.parse_args() @@ -27,18 +32,22 @@ registry = args.url repo = config["repo"] - tag = config["tag"] subprocess.run( - ["docker", "tag", f"{repo}:{tag}", f"{registry}/{repo}:{tag}"], check=True + ["docker", "tag", f"{repo}:{args.tag}", f"{registry}/{repo}:{args.tag}"], + check=True, ) Logger.i("[Instill Builder] Pushing model image...") - subprocess.run(["docker", "push", f"{registry}/{repo}:{tag}"], check=True) - Logger.i(f"[Instill Builder] {registry}/{repo}:{tag} pushed") - except subprocess.CalledProcessError as e: + subprocess.run(["docker", "push", f"{registry}/{repo}:{args.tag}"], check=True) + Logger.i(f"[Instill Builder] {registry}/{repo}:{args.tag} pushed") + except subprocess.CalledProcessError: Logger.e("[Instill Builder] Push failed") except Exception as e: Logger.e("[Instill Builder] Prepare failed") Logger.e(e) finally: Logger.i("[Instill Builder] Done") + + +if __name__ == "__main__": + push_image() diff --git a/pyproject.toml b/pyproject.toml index cca3cc3..6a90b7d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,6 +14,8 @@ homepage = "https://pypi.org/project/instill-sdk" documentation = "https://instill-sdk.readthedocs.io" repository = "https://github.com/instill-ai/python-sdk" +maintainers = ["Heiru Wu "] + keywords = [] classifiers = [ "Development Status :: 1 - Planning", @@ -37,7 +39,7 @@ googleapis-common-protos = "^1.60.0" protoc-gen-openapiv2 = "^0.0.1" pydantic = ">=1.10.13" pillow = "^10.1.0" -ray = {version = "2.9.3", extras = ["serve"]} +ray = { version = "2.9.3", extras = ["serve"] } jsonschema = "^4.20.0" [tool.poetry.dev-dependencies] @@ -84,8 +86,8 @@ jsonref = "^1.1.0" twine = "^4.0.2" [tool.poetry.scripts] - -# python-sdk = "instill.cli:main" +instill_build = "instill.helpers.build:build_image" +instill_push = "instill.helpers.push:push_image" [tool.black] @@ -118,9 +120,7 @@ profile = "black" skip_glob = ["**/protogen/*", "**/protobufs/*"] [tool.mypy] -exclude = [ - 'instill/resources/schema', -] +exclude = ['instill/resources/schema'] ignore_missing_imports = true no_implicit_optional = true check_untyped_defs = true