with something like this :
from typing import Annotated, Optional
import dagger
from dagger import Doc, dag, function, object_type
@object_type
class HelloDagger:
@function
async def build_discipline(
self,
source: Optional[Annotated[dagger.Directory, Doc("Source directory")]] = None,
) -> dagger.Container:
"""Builds the discipline service container using the specified configuration"""
# Get uv from its container
uv_container = dag.container().from_("ghcr.io/astral-sh/uv:0.5.8")
base = (
dag.container()
.from_("python:3.13")
.with_workdir("/app/")
# Explicitly copy uv binary to a directory in PATH
.with_file(
"/usr/local/bin/uv",
uv_container.file("/uv"),
permissions=0o755, # Executable permissions
)
# Verify uv is installed and executable
.with_exec(["sh", "-c", "uv --version"])
# Configure environment
.with_env_variable("PATH", "/app/.venv/bin:$PATH")
.with_env_variable("UV_COMPILE_BYTECODE", "1")
.with_env_variable("UV_LINK_MODE", "copy")
.with_env_variable("PYTHONPATH", "/app")
)
if source:
# Mount required files and directories if source is provided
base = (
base.with_file("/app/pyproject.toml", source.file("pyproject.toml"))
.with_file("/app/uv.lock", source.file("uv.lock"))
.with_file("/app/alembic.ini", source.file("alembic.ini"))
.with_mounted_directory("/app/app", source.directory("./app"))
)
return (
base
# Install dependencies
.with_exec(["uv", "sync", "--frozen", "--no-install-project"])
#
)