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/Directory | role | Git management |
|---|---|---|
| pyproject.toml | Project name, Python support scope, direct dependencies, development tools | Included |
| uv.lock | Dependency analysis results and package source/artifact information | Applications in this series include |
| .python-version | Python version hint to choose locally | Included |
| .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.
| command | Use |
|---|---|
| uv sync –locked | Verify that the specification and lock file are correct, and fail if a lock update is required. Useful for finding inconsistencies in CI |
| uv sync –frozen | Does not update lock files and uses existing locks without checking for compliance with the latest specification |
| uv sync –locked –no-default-groups | Synchronize only application dependencies without default dev group |
| uv sync –locked –no-default-groups –group notebook | Explicitly 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.



