Quản lý monorepo Python bằng UV Workspaces
(secondb.ai)Tóm tắt quản lý monorepo Python bằng UV Workspaces
Video này giới thiệu cách giải quyết gọn gàng các vấn đề phát sinh khi quản lý nhiều ứng dụng Python trong một kho Git duy nhất (monorepo) bằng tính năng UV Workspaces.
1. Tóm tắt video
Vấn đề
Khi đồng thời phát triển một công cụ CLI và một ứng dụng FastAPI trong cùng một repository, sẽ phát sinh các vấn đề sau.
- Trùng lặp mã nguồn: Các chức năng dùng chung giữa CLI và API (ví dụ: hàm crawl tiêu đề) phải được sao chép/dán lại.
- Quản lý môi trường phức tạp: Mỗi ứng dụng cần quản lý một môi trường ảo riêng, dễ gây xung đột phiên bản phụ thuộc hoặc lãng phí dung lượng đĩa.
Giải pháp: UV Workspaces
UV Workspaces cung cấp hai tính năng cốt lõi để giải quyết các vấn đề này.
-
Phụ thuộc dùng chung và một môi trường ảo duy nhất
- Có thể định nghĩa các phụ thuộc dùng chung trong tệp
pyproject.tomlở gốc dự án (cấp cao nhất). - Khi chạy lệnh
uv sync, UV sẽ đọc tệp cấu hình này và tạo một môi trường ảo duy nhất (.venv) trong thư mục gốc để dùng chung cho toàn bộ repository. - Nhờ đó, mọi dự án con (CLI, API, v.v.) sẽ chia sẻ cùng một môi trường và các phụ thuộc giống nhau, giúp tránh xung đột phiên bản và đơn giản hóa việc quản lý.
- Có thể định nghĩa các phụ thuộc dùng chung trong tệp
-
Chia sẻ mã nguồn qua gói nội bộ
- Có thể tách phần mã dùng chung bị trùng lặp (ví dụ: hàm
fetch_headlines) thành một "gói nội bộ" riêng nhưcore. - Thông qua cấu hình workspace, gói
corenày sẽ được nhận diện là nguồn cục bộ thay vì từ PyPI. - Từ đó, ứng dụng CLI và API có thể tái sử dụng mã chung này bằng cách
import, chẳng hạnfrom core.news import fetch_headlines.
- Có thể tách phần mã dùng chung bị trùng lặp (ví dụ: hàm
2. Cách sử dụng UV Workspaces
Bước 1: Cấu hình workspace
Tạo tệp pyproject.toml trong thư mục gốc của dự án, rồi định nghĩa phần [tool.uv.workspace] để chỉ ra vị trí của các dự án con.
[tool.uv.workspace]
# Nhận diện mọi thư mục con trong thư mục "packages" là thành viên workspace
members = ["packages/*"]
Bước 2: Quản lý phụ thuộc
- Phụ thuộc dùng chung: Các phụ thuộc được tất cả dự án cùng sử dụng (ví dụ:
python-dotenv) nên được thêm vàopyproject.tomlở gốc. - Phụ thuộc riêng: Các phụ thuộc chỉ dùng cho một ứng dụng cụ thể (ví dụ:
fastapi,uvicornchỉ choapi) nên được thêm vàopyproject.tomlcủa ứng dụng đó (ví dụ:packages/api/pyproject.toml). - Khi chạy
uv syncở thư mục gốc, UV sẽ quét mọipyproject.tomlvà cài toàn bộ phụ thuộc cần thiết vào môi trường ảo ở gốc.
Bước 3: Chia sẻ mã bằng gói nội bộ
- Tạo một gói (thư mục) mới chứa mã dùng chung, ví dụ
packages/core. - Thêm gói này vào
pyproject.tomlở gốc như một phụ thuộc thông thường. - Thêm phần
[tool.uv.sources]vàopyproject.tomlở gốc để cấu hình cho UV tìm góicorebên trong workspace thay vì trên PyPI.
[project]
# 1. Thêm gói nội bộ làm phụ thuộc
dependencies = [
"core",
"python-dotenv"
]
# 2. Khai báo 'core' là gói cục bộ trong workspace
[tool.uv.sources]
core = { workspace = true }
- Chạy lại
uv sync, khi đó góicoresẽ được cài từ nguồn cục bộ. - Giờ đây, trong
packages/apihoặcpackages/cli, bạn có thể dùng cú phápfrom core.news import ...để gọi mã dùng chung.
Bước 4: Chạy dự án
Khi chạy một dự án cụ thể, hãy dùng uv run --from <tên_gói>.
# Chạy máy chủ API
uv run --from packages/api uvicorn main:app --reload
# Chạy công cụ CLI
uv run --from packages/cli python main.py
3. Đối tượng nên dùng
- Phù hợp khi quản lý nhiều script tự động hóa nhỏ, webhook, API, CLI, v.v. trong cùng một repository.
- Đặc biệt hữu ích khi các ứng dụng này cùng chia sẻ logic hoặc phụ thuộc chung.
- Ngược lại, có thể không phù hợp để quản lý một script đơn lẻ, một gói sẽ được phát hành độc lập lên PyPI, hoặc các ứng dụng hoàn toàn không liên quan đến nhau.
Liên kết video gốc: https://www.youtube.com/watch?v=N_ypJwV8Q8I
1 bình luận
Khá giống với pnpm.