diff --git a/.github/workflows/base-image.yml b/.github/workflows/base-image.yml index d290d49a..e3a8a4ee 100644 --- a/.github/workflows/base-image.yml +++ b/.github/workflows/base-image.yml @@ -6,13 +6,13 @@ on: paths: - 'docker/DispatcharrBase' - '.github/workflows/base-image.yml' - - 'requirements.txt' + - 'pyproject.toml' pull_request: branches: [main, dev] paths: - 'docker/DispatcharrBase' - '.github/workflows/base-image.yml' - - 'requirements.txt' + - 'pyproject.toml' workflow_dispatch: # Allow manual triggering permissions: diff --git a/.gitignore b/.gitignore index 20968f46..6d1becaa 100755 --- a/.gitignore +++ b/.gitignore @@ -19,4 +19,5 @@ debugpy* uwsgi.sock package-lock.json models -.idea \ No newline at end of file +.idea +uv.lock \ No newline at end of file diff --git a/docker/DispatcharrBase b/docker/DispatcharrBase index 149bfffb..d2e8ceaa 100644 --- a/docker/DispatcharrBase +++ b/docker/DispatcharrBase @@ -1,8 +1,11 @@ FROM lscr.io/linuxserver/ffmpeg:latest ENV DEBIAN_FRONTEND=noninteractive +ENV UV_PROJECT_ENVIRONMENT=/dispatcharrpy ENV VIRTUAL_ENV=/dispatcharrpy ENV PATH="$VIRTUAL_ENV/bin:$PATH" +ENV UV_COMPILE_BYTECODE=1 +ENV UV_LINK_MODE=copy # --- Install Python 3.13 and build dependencies --- # Note: Hardware acceleration (VA-API, VDPAU, NVENC) already included in base ffmpeg image @@ -18,24 +21,28 @@ RUN apt-get update && apt-get install --no-install-recommends -y \ vlc-bin vlc-plugin-base \ build-essential gcc g++ gfortran libopenblas-dev libopenblas0 ninja-build -# --- Create Python virtual environment --- -RUN python3.13 -m venv $VIRTUAL_ENV && $VIRTUAL_ENV/bin/pip install --upgrade pip +# --- Install UV --- +COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/ -# --- Install Python dependencies --- -COPY requirements.txt /tmp/requirements.txt -RUN $VIRTUAL_ENV/bin/pip install --no-cache-dir -r /tmp/requirements.txt && \ - rm /tmp/requirements.txt +# --- Create Python virtual environment and install dependencies --- +WORKDIR /tmp/build +COPY pyproject.toml /tmp/build/ +COPY version.py /tmp/build/ +COPY README.md /tmp/build/ +RUN uv sync --python 3.13 --no-cache --no-install-project --no-dev && \ + rm -rf /tmp/build +WORKDIR / # --- Build legacy NumPy wheel for old hardware (store for runtime switching) --- -RUN $VIRTUAL_ENV/bin/pip install --no-cache-dir build && \ +RUN uv pip install --python $UV_PROJECT_ENVIRONMENT/bin/python --no-cache build pip && \ cd /tmp && \ - $VIRTUAL_ENV/bin/pip download --no-binary numpy --no-deps numpy && \ + $UV_PROJECT_ENVIRONMENT/bin/python -m pip download --no-binary numpy --no-deps numpy && \ tar -xzf numpy-*.tar.gz && \ cd numpy-*/ && \ - $VIRTUAL_ENV/bin/python -m build --wheel -Csetup-args=-Dcpu-baseline="none" -Csetup-args=-Dcpu-dispatch="none" && \ + $UV_PROJECT_ENVIRONMENT/bin/python -m build --wheel -Csetup-args=-Dcpu-baseline="none" -Csetup-args=-Dcpu-dispatch="none" && \ mv dist/*.whl /opt/ && \ cd / && rm -rf /tmp/numpy-* /tmp/*.tar.gz && \ - $VIRTUAL_ENV/bin/pip uninstall -y build + uv pip uninstall --python $UV_PROJECT_ENVIRONMENT/bin/python build pip # --- Clean up build dependencies to reduce image size --- RUN apt-get remove -y build-essential gcc g++ gfortran libopenblas-dev libpcre3-dev python3.13-dev ninja-build && \ diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..9400a55d --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,56 @@ +[project] +name = "dispatcharr" +description = "Dispatcharr - Stream dispatching and management" +readme = "README.md" +license = "CC-BY-NC-SA-4.0" +requires-python = ">=3.13" +dynamic = ["version"] +dependencies = [ + "Django==5.2.9", + "psycopg2-binary==2.9.11", + "celery[redis]==5.6.0", + "djangorestframework==3.16.1", + "requests==2.32.5", + "psutil==7.1.3", + "pillow", + "drf-spectacular>=0.29.0", + "streamlink", + "python-vlc", + "yt-dlp", + "gevent==25.9.1", + "daphne", + "uwsgi", + "django-cors-headers", + "djangorestframework-simplejwt", + "m3u8", + "rapidfuzz==3.14.3", + "regex", + "tzlocal", + "pytz", + "torch==2.9.1+cpu", + "sentence-transformers==5.2.0", + "channels", + "channels-redis==4.3.0", + "django-filter", + "django-celery-beat", + "lxml==6.0.2", +] + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +# PyTorch CPU-only wheels index +[[tool.uv.index]] +url = "https://download.pytorch.org/whl/cpu" +name = "pytorch-cpu" +explicit = true + +[tool.uv.sources] +torch = { index = "pytorch-cpu" } + +[tool.hatch.build.targets.wheel] +packages = ["dispatcharr", "apps", "core"] + +[tool.hatch.version] +path = "version.py"