Skip to content

Instantly share code, notes, and snippets.

@P403n1x87
Last active October 9, 2022 11:17
Show Gist options
  • Save P403n1x87/85d25a54d98a54eb585b1974f030c885 to your computer and use it in GitHub Desktop.
Save P403n1x87/85d25a54d98a54eb585b1974f030c885 to your computer and use it in GitHub Desktop.
Install Kodi Python plugin dependencies from PyPI using pip
# Use as
#
# import deps
#
# deps.install(dict(requests="2.28.1"))
#
import json
import os
import site
import subprocess
import sys
import typing as t
from contextlib import contextmanager
from pathlib import Path
HERE = Path(__file__).parent
VENV_PREFIX = HERE / ".venv"
@contextmanager
def metadata() -> t.Iterator[dict]:
"""Load and persist metadata."""
METADATA = HERE / ".metadata.json"
md = json.loads(METADATA.read_text()) if METADATA.exists() else {}
yield md
METADATA.write_text(json.dumps(md, indent=4))
ENV = os.environ.copy()
path = ENV.get("PATH", None)
ENV["PATH"] = (
os.pathsep.join(
[
str(VENV_PREFIX / "bin"),
path,
]
)
if path is not None
else str(VENV_PREFIX / "bin")
)
def create_venv() -> None:
"""Create a virtual environment.
Return the environment variables required to use the virtual environment.
"""
subprocess.run(
[
sys.executable,
"-m",
"venv",
str(VENV_PREFIX),
],
check=True,
)
subprocess.run(
[
"pip",
"install",
"--upgrade",
"pip",
],
check=True,
env=ENV,
)
def install(dependencies: t.Dict[str, str]) -> None:
with metadata() as md:
# Check if venv has been created
if not md or md.get("venv") != str(VENV_PREFIX):
create_venv()
md["venv"] = str(VENV_PREFIX)
# Check if dependencies need to be installed
if not md or md.get("dependencies", {}) != dependencies:
subprocess.run(
[
# "python",
# "-m",
"pip",
"--disable-pip-version-check",
"install",
"--no-warn-script-location",
"--prefix",
str(VENV_PREFIX),
*("==".join(d) for d in dependencies.items()),
],
check=True,
env=ENV,
)
# Persist dependency information to avoid reinstalling next time
md["dependencies"] = dependencies
# Ensure that the dependency prefix is added to the path so that we can
# import the newly installed dependencies.
sys.path[0:0] = site.getsitepackages(prefixes=[str(VENV_PREFIX)])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment