MaruOpsInfrastructure and AI notes

About (Korean)Contact (Korean)

[Python Environments 02] Use uv for Python, Dependencies and Lockfiles

Workspace with desktop computer, keyboard, and tablet

Reference photo · Workspace with desktop computer, keyboard, and tablet · Photo: William Iven firmbee / Source / CC0 · Resized for listings; illustrative photo, not the tested environment

A reproducible project records both the dependencies it needs and the resolved versions used to run it. uv connects Python selection, project dependencies, lockfiles and environment synchronization. Follow that workflow so the environment can be reviewed and rebuilt when the project changes hands.

Python development environment · 01 selection and venv · 02 uv · 03 conda · 04 web Development·05 Data·AI·06 OCR·Service Separation

On this page

Differentiate the roles of the four files

File/DirectoryroleGit management
pyproject.tomlProject name, Python support scope, direct dependencies, development toolsIncluded
uv.lockDependency analysis results and package source/artifact informationApplications in this series include
.python-versionPython version hint to choose locallyIncluded
.venv/The actual execution environment created on the current machine.Exclude and recreate

uv.lock is an important material for reproducing Python packages, but it is not a file that fixes OS image, GPU driver, DB, and model data. Also, if you only write 3.12 in .python-version, the patch version is not fixed to one. We also record Python patches and OS images, depending on the level required for operational reproducibility.

1. Install UV in common for Ubuntu and Rocky.

The uv that confirmed the example in this article on October 18, 2026 is 0.13.1. Below is how to download the corresponding version installation script. After checking the contents of the installation file, run it with normal user privileges. For later versions, please select , check the official installation guide, , and check the changes.

curl -LsSf https://astral.sh/uv/0.13.1/install.sh -o uv-install.sh
less uv-install.sh
sh uv-install.sh
source "$HOME/.local/bin/env"
uv --version

For networks with limited installation script access, you can also install the official PyPI package into a dedicated bootstrap venv. We used this path in our validation work. It can be called with the full path of the executable file, as shown in the last line below, and does not change the system Python area.

python3.12 -m venv "$HOME/.local/share/uv-bootstrap"
"$HOME/.local/share/uv-bootstrap/bin/python" -m pip install 'uv==0.13.1'
"$HOME/.local/share/uv-bootstrap/bin/uv" --version

The subsequent commands in the text assume that uv is in the PATH. If you used the bootstrap method, use the executable path above instead of uv or link just that executable to your user bin. The entire Bootstrap venv is not used like Project Python.

2. Select project and Python

uv python install 3.12
uv init --app --python 3.12 uv-demo
cd uv-demo
uv python pin 3.12

You can use Python 3.12 prepared by the OS as is, or you can install Python managed by uv. The managed executor installed by uv python install is managed separately from /usr/bin/python3 on your system. You can check the distribution method and supported platforms at uv’s Python installation guide.

3. Divide dependencies in pyproject.toml

Match the generated pyproject.toml to the example below. Limiting the scope of Python to the 3.12 series is a common practice condition for this series, and does not mean that this scope must be applied to all projects. Support for higher versions is expanded by checking core packages and testing.

[project]
name = "uv-demo"
version = "0.1.0"
requires-python = ">=3.12,<3.13"
dependencies = ["requests>=2.32,<3"]

[dependency-groups]
dev = ["pytest>=8,<10", "ruff>=0.11,<1"]
notebook = ["ipykernel>=6,<8"]

Common changes can be like uv add requests, uv add --dev pytest ruff, uv add --group notebook ipykernel. If you have already created the above file, you do not need to add the same dependency again. You will lock and install your edited specification in the next step.

The dev group is included in the default installation target, but other groups, such as notebook, can be selected for installation. However, Dividing groups does not result in different Python environments. When analyzing locks, compatibility of groups and extras is considered together, so large frameworks that conflict with each other are not included in one project by dividing only the group names. Please refer to Dependency Group Guide and Dependency Interpretation Rules.

4. Lock, Run and Test

First, enter the following content that outputs the launcher and requests version in main.py, and also save the test file.

import sys

import requests

print(sys.executable)
print("requests", requests.__version__)

tests/test_env.py

import sys

import requests


def test_project_interpreter():
    assert sys.prefix != sys.base_prefix


def test_requests_imports():
    assert requests.__version__
uv lock
uv sync --locked
uv run --locked python -c 'import sys, requests; print(sys.executable); print(requests.__version__)'
uv run --locked python main.py
uv run --locked python -m pytest
uv pip check

uv run can perform the necessary environment synchronization before execution, so there is no need to activate every time. Conversely, packages arbitrarily installed with uv pip install cannot replace the project dependency declaration and may be removed in the next sync. Changes to team project dependencies are made through uv add or specification modification.

–locked and –frozen are not used interchangeably.

commandUse
uv sync –lockedVerify that the specification and lock file are correct, and fail if a lock update is required. Useful for finding inconsistencies in CI
uv sync –frozenDoes not update lock files and uses existing locks without checking for compliance with the latest specification
uv sync –locked –no-default-groupsSynchronize only application dependencies without default dev group
uv sync –locked –no-default-groups –group notebookExplicitly include the notebook group instead of the default dev

If you mix options based on the commonality of “do not change lock files”, you may miss pyproject changes. The CI examples in this series use --locked. Detailed operation was confirmed based on lock and synchronization document .

5. Restore the environment and update packages

Check pyproject.toml·uv.lock·.python-version in the newly received repository and then run uv sync --locked. When testing a restore, do not delete the original code directory but check it in a separate new checkout or copy.

# 프로젝트 루트에서 선택한 패키지만 업데이트 검토
uv lock --upgrade-package requests
git diff -- pyproject.toml uv.lock
uv sync --locked
uv run --locked python -m pytest

Run tests before and after an update, then commit the project specification and lockfile together. uv makes dependency changes available for code review as well as providing short installation commands. If native packages or a particular channel combination dominate the project, also compare Part 03: conda.

Download series example file·venv·conda specification, uv·web·data·OCR example source, and confirmed uv lock file are bundled. It is executed from each project directory, and the OS package is prepared separately through the procedures in the main text.