Skip to content
Open
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
5dc2f9c
update tool.ruff target-version to py311
fujikosu Mar 17, 2025
313d1c7
migrate notebook container to uv
fujikosu Mar 17, 2025
94e043d
migrate sample_cpu_project to uv
fujikosu Mar 17, 2025
e9a0261
fix comment in Dockerfile
fujikosu Mar 17, 2025
586536a
remove unused requirements.txt
fujikosu Mar 17, 2025
f8b9686
migrate gpu container to uv
fujikosu Mar 17, 2025
34ded4d
use uv in CI
fujikosu Mar 17, 2025
eb44d7a
add cuda version check in sample. switch base container from cuda to …
fujikosu Mar 18, 2025
2a2005c
update dockerfiles to use UID 1000
fujikosu Mar 26, 2025
205caae
add uv support to dependabot
fujikosu Mar 28, 2025
4e12d15
add uv related docs
fujikosu Mar 28, 2025
0da499b
add .DS_Store to gitignore
fujikosu Mar 28, 2025
befd97d
update docs to uv version
fujikosu Mar 28, 2025
c2ad412
tested uv install commands and updated readme
fujikosu Mar 28, 2025
9c46482
Merge branch 'main' into feat/migrate-to-uv-from-pip
fujikosu Apr 13, 2025
e927088
update uv lock procedure doc
fujikosu Apr 13, 2025
b24c6c7
update azdo pipelines
fujikosu Apr 13, 2025
246331d
fix permission issue for certifi
fujikosu Apr 13, 2025
8048cf8
permission fix
fujikosu Apr 13, 2025
bff3a98
get rid of cuda 12.6 setting to default back to 12.4
fujikosu Apr 13, 2025
0a73e70
updated lockfile
fujikosu Apr 13, 2025
7523729
update README to include more mentions about uv and PR template
fujikosu Apr 13, 2025
3e38a95
update Dockerfiles to change UV_LINK_MODE and make use of mounted cache
fujikosu Jul 19, 2025
a2b10fb
fix the mount path in gpu container
fujikosu Jul 19, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .azuredevops/ado-ci-pipeline-ms-hosted.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ steps:
python -m venv venv
source venv/bin/activate
python -m pip install --upgrade pip
pip install -r requirements-dev.txt
pip install pytest-azurepipelines
pip install ruff pytest-azurepipelines
displayName: "Install requirements"

# files under venv will be automatically excluded from ruff check by default https://docs.astral.sh/ruff/settings/#exclude
Expand Down
3 changes: 1 addition & 2 deletions .azuredevops/ado-ci-pipeline-self-hosted.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,7 @@ steps:
python -m venv venv
source venv/bin/activate
python -m pip install --upgrade pip
pip install -r requirements-dev.txt
pip install pytest-azurepipelines
pip install ruff pytest-azurepipelines
displayName: "Install requirements"

- task: UseDotNet@2
Expand Down
11 changes: 11 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,17 @@ updates:
update-types:
- "minor"
- "patch"
- package-ecosystem: "uv"
directories:
- "**/*"
schedule:
interval: "monthly"
groups:
uv-minor-patch-updates:
applies-to: version-updates
update-types:
- "minor"
- "patch"
- package-ecosystem: "github-actions"
# Workflow files stored in the default location of `.github/workflows`. (You don't need to specify `/.github/workflows` for `directory`. You can use `directory: "/"`.)
directory: "/"
Expand Down
2 changes: 1 addition & 1 deletion .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

* [ ] No PII in logs or output
* [ ] Made corresponding changes to the documentation
* [ ] All new packages used are included in requirements.txt
* [ ] All new packages used are included in pyproject.toml
* [ ] Functions use type hints, and there are no type hint errors

## Pull Request Type
Expand Down
17 changes: 3 additions & 14 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,12 @@ jobs:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Python 3.11
uses: actions/setup-python@v5
with:
python-version: 3.11

- name: Install requirements
run: |
python -m venv venv
source venv/bin/activate
python -m pip install --upgrade pip
pip install -r requirements-dev.txt
- name: Install uv
uses: astral-sh/setup-uv@v5

- name: Run ruff linter
# files under venv will be automatically excluded from ruff check by default https://docs.astral.sh/ruff/settings/#exclude
run: |
source venv/bin/activate
ruff check --output-format github
uvx ruff check --output-format github

- name: Run pytest in docker containers
run: ./ci-tests.sh
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
data
logs
.vscode
.DS_Store

# Byte-compiled / optimized / DLL files
__pycache__/
Expand Down
35 changes: 27 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Dev Containers for ML feasibility study with VS Code

A machine learning and data science project template that makes it easy to work with multiple Docker based [VSCode Dev Containers](https://code.visualstudio.com/docs/devcontainers/containers) in the same repository. The template also makes it easy to transition projects to the cloud and production by including automated code quality checks, pytest configuration, CI pipeline templates and a sample for running on Azure Machine Learning.
[![CI](https://github.com/microsoft/dstoolkit-devcontainers/actions/workflows/ci.yaml/badge.svg?branch=main)](https://github.com/microsoft/dstoolkit-devcontainers/actions/workflows/ci.yaml)

A machine learning and data science project template that makes it easy to work with multiple Docker based [VSCode Dev Containers](https://code.visualstudio.com/docs/devcontainers/containers) in the same repository. The template leverages [uv](https://github.com/astral-sh/uv), an extremely fast Python package and project manager as a base for better productivity. The template also makes it easy to transition projects to the cloud and production by including automated code quality checks, pytest configuration, CI pipeline templates and a sample for running on Azure Machine Learning.

## Contents

Expand All @@ -10,7 +12,7 @@ A machine learning and data science project template that makes it easy to work
- [Features](#features)
- [Getting Started](#getting-started)
- [How to setup dev environment?](#how-to-setup-dev-environment)
- [How to create a new directory under src with a new environment](#how-to-create-a-new-directory-under-src-with-a-new-environment)
- [How to update python packages in the dev container](#how-to-update-python-packages-in-the-dev-container)
- [Directory Structure](#directory-structure)
- [`notebooks` directory vs `src` directory](#notebooks-directory-vs-src-directory)
- [AML Example](#aml-example)
Expand Down Expand Up @@ -57,15 +59,32 @@ This section provides a comprehensive guide on how to set up a development envir
1. Run `Dev Containers: Open Folder in Container...` from the Command Palette (F1) and select the `notebooks` directory.
1. VS Code will then build and start up a container, connect this window to Dev Container: `notebooks`, and install VS Code extensions specified in `notebooks/.devcontainer/devcontainer.json`. `pre-commit install --overwrite` runs as part of `postCreateCommand` in `devcontainer.json` and this will setup your git precommit hook automatically.
1. Now set up is done. If you want to develop in another directory for example under `src`, run `Dev Containers: Open Folder in Container...` and go to that directory that has `.devcontainer` and that will setup an dev environment for that directory.
1. When you or others update either `requirements.txt` or `Dockerfile` in your working directory, make sure to rebuild your container to apply those changes to container. Run `Dev Containers: Rebuild and Reopen in Container...` for that.
1. When you or others update either `pyproject.toml` or `Dockerfile` in your working directory, make sure to rebuild your container to apply those changes to container. Run `Dev Containers: Rebuild and Reopen in Container...` for that.

## How to create a new directory under src with a new environment

1. Copy `src/sample_cpu_project/` under `src` and rename it. If you need gpu environment, base off of `src/sample_pytorch_gpu_project` instead
1. Update `COPY sample_cpu_project/.devcontainer/requirements.txt` in `Dockerfile` with a new path
1. Update `COPY src/sample_cpu_project/.devcontainer/pyproject.toml src/sample_cpu_project/.devcontainer/uv.lock` in `Dockerfile` with a new path
1. Update other parts of `Dockerfile` if you need
1. Update `requirements.txt` if you need
1. Run `Dev Containers: Open Folder in Container...` from the Command Palette (F1) and select the new directory and make sure you can successfully open the new directory on VS Code running in a container
1. If you need to update python packages, stay inside DevContainer you just built and follow the steps below
1. Update `.devcontainer/pyproject.toml` and add/remove new python packages you need in `project.dependencies` section
1. Run `uv lock --project $UV_PROJECT_FILE` to update the project's lockfile `.devcontainer/uv.lock` with the updated python packages. `$UV_PROJECT_FILE` is already set automatically during docker build so you don't need to manually set it
1. Rerun `Dev Containers: Open Folder in Container...` from the Command Palette (F1) and select the new directory and make sure you can successfully open the new directory on VS Code running in a container

## How to update python packages in the dev container

This solution uses [uv](https://docs.astral.sh/uv) to manage python packages in the dev container. `uv` is a fast and efficient Python package and project manager that simplifies dependency management and ensures consistency across environments. It is installed in the dev container and is used to manage python packages in the dev container. `uv` is also used to create a lock file (`uv.lock`) that contains the list of all python packages and their versions that are installed in the dev container. This lock file is used to ensure that the same versions of the packages and dependencies are installed in every devcontainer build.

To manage Python packages within your active dev container, execute the following commands according to your needs:

- To add a package: `uv add requests --project $UV_PROJECT_FILE`
- To add a specific version of a package: `uv add 'requests==2.31.0' --project $UV_PROJECT_FILE`
- To remove a package: `uv remove requests --project $UV_PROJECT_FILE`
- To upgrade a package: `uv lock --upgrade-package requests --project $UV_PROJECT_FILE`

These commands update both `pyproject.toml` and `uv.lock` files automatically.
Check for more details at [The official documentation for how to manage dependencies in uv](https://docs.astral.sh/uv/guides/projects/#managing-dependencies)

## Directory Structure

Expand All @@ -83,7 +102,7 @@ This section gives you overview of the directory structure of this template. Onl
│ ├── .devcontainer # dev container related configuration files goes to here following VSCode convention
│ │ ├── devcontainer.json # dev container configuration and VS Code settings, extensions etc.
│ │ ├── Dockerfile # referred in devcontainer.json
│ │ └── requirements.txt # includes python package list for notebooks. used in Dockerfile
│ │ └── pyproject.toml # includes python package list for notebooks. used in Dockerfile
│ └── sample_notebook.py # example of interactive python script
├── pyproject.toml # Setting file for ruff, pytest and pytest-cov
└── src
Expand All @@ -93,7 +112,7 @@ This section gives you overview of the directory structure of this template. Onl
│ ├── .devcontainer # dev container related configuration files goes to here following VSCode convention
│ │ ├── devcontainer.json # dev container configuration and VS Code settings, extensions etc.
│ │ ├── Dockerfile # referred in devcontainer.json. Supports only CPU
│ │ └── requirements.txt # includes python package list for sample_cpu_project. used in Dockerfile
│ │ └── pyproject.toml # includes python package list for sample_cpu_project. used in Dockerfile
│ ├── sample_main.py
│ └── tests # pytest scripts for sample_cpu_project goes here
│ └── test_dummy.py # pytest script example
Expand All @@ -102,7 +121,7 @@ This section gives you overview of the directory structure of this template. Onl
├── .devcontainer # dev container related configuration files goes to here following VSCode convention
│ ├── devcontainer.json # dev container configuration and VS Code settings, extensions etc.
│ ├── Dockerfile # referred in devcontainer.json. Supports GPU
│ └── requirements.txt # includes python package list for sample_pytorch_gpu_project. used in Dockerfile
│ └── pyproject.toml # includes python package list for sample_pytorch_gpu_project. used in Dockerfile
├── aml_example/ # Sample AML CLI v2 Components-based pipeline, including setup YAML. See sample_pytorch_gpu_project/README for full details of files in this directory.
├── sample_main.py
├── inference.py # Example pytorch inference/eval script that also works with aml_example
Expand Down
21 changes: 14 additions & 7 deletions notebooks/.devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
FROM python:3.11.11
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/

# create non-root user and set the default user
ARG USERNAME=devuser
ARG USER_UID=1000
Expand All @@ -11,14 +13,19 @@ RUN groupadd --gid $USER_GID $USERNAME \
&& echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \
&& chmod 0440 /etc/sudoers.d/$USERNAME \
&& rm -rf /var/lib/apt/lists/*
# some packages try to create new directories in /usr/local/lib/python3.11/site-packages etc during uv sync so permission needs to be granted
RUN chown -R $USERNAME:$USERNAME /usr/local
USER $USERNAME

# make all python tools installed by pip accesible
# make all python tools installed by uv accessible
ENV PATH=$PATH:/home/$USERNAME/.local/bin
RUN pip install --no-cache-dir pip --upgrade
COPY requirements-dev.txt .
RUN pip install --no-cache-dir -r requirements-dev.txt
# it tends to improve startup time (at the cost of increased installation time)
ENV UV_COMPILE_BYTECODE=1
# This prevents uv from creating venv but instead makes it use the system python in container
ENV UV_PROJECT_ENVIRONMENT=/usr/local
ENV UV_PROJECT_FILE=.devcontainer/pyproject.toml
RUN sudo chown -R $USERNAME:$USERNAME /usr/local

# install notebooks related depencencies
COPY notebooks/.devcontainer/requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# install notebooks related dependencies & python dev tools
COPY notebooks/.devcontainer/pyproject.toml notebooks/.devcontainer/uv.lock ./
RUN uv sync --no-cache --project $UV_PROJECT_FILE --frozen
21 changes: 21 additions & 0 deletions notebooks/.devcontainer/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[project]
name = ""
version = "0.1.0"
requires-python = ">=3.11"
dependencies = [
"ipykernel==6.29.5",
"nbconvert==7.16.6",
"nbformat==5.10.4",
]

[dependency-groups]
dev = [
"mypy==1.15.0",
"pytest==8.3.5",
"pre-commit==4.2.0",
"pytest-cov==6.1.0",
"ruff==0.11.2",
]

[tool.uv]
package = false
4 changes: 0 additions & 4 deletions notebooks/.devcontainer/requirements.txt

This file was deleted.

Loading