FDE PulseViệc làm FDE đang mở 441Mới trong 7 ngày 29Công ty đang tuyển 47Nhận làm từ xa 24%Lương trung vị (Mỹ) $216kTuyển nhiều nhất Databricks 125
EN

Tờ báo của nghề Forward Deployed Engineer

Công cụ

uv: một lockfile, một lệnh sync, và môi trường Python dựng lại được trên máy khách

Pipeline chạy tốt trên laptop nhưng gãy trên server của khách thường là do môi trường bị lệch, và uv được làm ra để chặn đúng chỗ lệch đó.

Ảnh chụp màn hình laptop hiển thị code Python và cửa sổ terminal, hoặc kỹ sư đang làm việc cạnh tủ máy chủ trong phòng server.
Ảnh: Negative Space / CC0

Tóm tắt nhanh

  • uv.lock là lockfile dùng được trên mọi hệ điều hành và phải được commit. Còn .venv thì không commit, máy nào cũng tự dựng lại bằng uv sync.
  • File .python-version ghim bản Python của dự án. Nếu máy khách chưa có bản đó, mặc định uv sẽ tự tải về.
  • Các con số về tốc độ không thống nhất với nhau. Lý do đáng để FDE dùng uv là môi trường dựng lại được, còn tốc độ chỉ là phần thưởng thêm.
Chia sẻLinkedInFacebookX
Đồ hoạuv lo được gì, FDE vẫn phải tự lo gì
uv lo đượcBạn vẫn phải tự lo
Bản Python.python-version ghim bản cần dùng, thiếu thì uv tự tải vềMáy khách phải có đường ra mạng để tải
Package Pythonuv.lock resolve cho mọi nền tảng, dựng lại bằng uv syncDriver, thư viện hệ thống, cấu hình máy nằm ngoài lockfile
Script gửi lẻKhai báo dependency trong file theo PEP 723 và khóa lạiKhóa trước khi gửi và chạy thử trên một máy sạch
Tốc độTài liệu ghi nhanh hơn pip 10-100 lầnTự đo trên hạ tầng khách trước khi hứa con số

uv khóa được phần Python, còn mạng, thư viện hệ thống và cam kết tốc độ vẫn là việc của bạn.

Đồ hoạ: FDE Times

README của uv liệt kê những công cụ nó muốn thay: pip, pip-tools, pipx, poetry, pyenv, twine, virtualenv, rồi thêm chữ “và nhiều hơn nữa”. FDE nào từng dựng cùng một pipeline trên laptop Mac của mình, server Linux của khách này và máy Windows của khách kia sẽ thấy danh sách đó quen. Mỗi cái tên trong đó là một chỗ môi trường có thể lệch nhau.

Astral, công ty làm ra Ruff, giới thiệu uv là trình quản lý package và dự án Python viết bằng Rust và “cực kỳ nhanh”. Tuy vậy, tốc độ không phải lý do chính để FDE học công cụ này. Lý do chính là tính lặp lại: code bạn giao phải chạy giống nhau trên những máy bạn không quản lý và có khi chưa từng thấy.

Nếu bạn đang muốn chuyển sang FDE, kỹ năng này đáng tập sớm, vì công việc của FDE là giao code chạy trên hạ tầng của người khác. Demo trên máy bạn chạy được thì chưa nói lên điều gì. Thứ được tính là lệnh đầu tiên chạy được trên máy của khách.

Lỗi thường không nằm ở code

Thử hình dung một tình huống. Bạn viết một service phân loại tài liệu trên Mac, test kỹ rồi đẩy lên Git. Kỹ sư phía khách clone repo về một máy Windows, cài thư viện với bản Python sẵn có trên máy, và gặp lỗi import ngay ở dòng đầu.

Có ba nguyên nhân hay gặp. Bản Python trên máy khách khác với máy bạn, các thư viện được resolve vào một ngày khác nên kéo về phiên bản khác, hoặc lockfile của bạn chỉ đúng cho hệ điều hành nơi nó được tạo ra. uv có cách xử lý riêng cho cả ba nguyên nhân này.

Ba file và một lệnh

Dù dự án đang dùng requirements.txt hay một công cụ khác, đích đến khi chuyển sang uv là một repo có ba thứ sau:

du-an-khach/
├── .python-version   # commit
├── uv.lock           # commit
└── .venv/            # KHÔNG commit

File .python-version ghim bản Python của dự án. File uv.lock ghi lại các package sẽ được cài, và tài liệu của uv nhấn mạnh rằng file này phải nằm trong version control. Thư mục .venv là môi trường thật trên từng máy, không được commit vì máy nào cũng có thể dựng lại nó từ lockfile.

Trên máy khách, sau khi clone repo, bạn chỉ cần chạy:

uv sync

uv đọc .python-version. Nếu máy chưa có bản Python phù hợp, mặc định uv sẽ tự tải về, nên khách không cần cài sẵn đúng phiên bản. Sau đó uv dựng .venv theo đúng những gì uv.lock đã ghi.

Mấu chốt nằm ở chữ “universal”. uv tạo lockfile bằng cách resolve cho mọi nền tảng, nên cùng một uv.lock dùng được trên nhiều hệ điều hành. Nếu không resolve theo kiểu đó, lockfile chỉ đúng trên nền tảng đã tạo ra nó, và đó chính là kiểu lỗi Mac sang Windows trong tình huống ở trên.

Khi khách muốn chạy lại đúng như tháng trước

Ở chỗ khách có một yêu cầu rất hay gặp: báo cáo tháng trước ra một con số, giờ chạy lại thì ra con số khác, và khách muốn biết vì sao.

Nếu lockfile được commit cùng với code thì việc quay về commit cũ đã giải quyết phần lớn. Khi phải resolve lại từ đầu, uv có tùy chọn --exclude-newer để chỉ dùng những bản phân phối đã được upload trước một ngày cụ thể.

Còn một trường hợp nhỏ hơn: một script làm sạch dữ liệu bạn viết vội để gửi cho chuyên viên phân tích bên khách. uv cho phép khai báo dependency ngay trong file script theo PEP 723 và khóa script đơn lẻ đó lại. Tài liệu của uv nói rõ mục đích là để script chạy lại về sau vẫn dựng được đúng môi trường như cũ.

Những lỗi hay gặp

Nó nặng, gắn với máy đã tạo ra nó, và hoàn toàn thừa khi uv sync đã dựng lại được môi trường từ lockfile.

Lỗi ngược lại là bỏ uv.lock ra khỏi Git vì nghĩ đó là file sinh tự động. Không có lockfile, máy khách sẽ resolve lại vào một ngày khác và bạn quay về đúng tình huống lỗi import ở trên.

Với script gửi lẻ, lỗi hay gặp là chỉ khai báo dependency mà không khóa. Danh sách thư viện thì có, nhưng phiên bản được chọn sẽ tùy vào ngày chạy. Trước khi gửi, hãy khóa script và tự chạy thử trên một máy sạch để chắc khách nhận được đủ những gì cần.

uv không làm thay bạn những gì

Trước hết là con số về tốc độ. Trang tài liệu chính thức ghi uv nhanh hơn pip từ 10 đến 100 lần, còn bài ra mắt của Charlie Marsh ngày 15/2/2024 đưa ra mức nhanh hơn 8-10 lần so với pip và pip-tools khi không có cache.

Hai con số không trùng nhau, nên con số nào cũng chưa phải lời hứa dành cho hạ tầng của khách. Nếu muốn nói chuyện tốc độ, hãy tự đo trên máy của họ trước.

Việc tự tải Python rất tiện nhưng cần máy khách có đường ra mạng. Ở những môi trường bị khóa mạng, bạn nên hỏi ngay từ buổi kickoff và chuẩn bị phương án khác. Ngoài ra, uv.lock chỉ ghi lại các package Python; driver, thư viện hệ thống hay cấu hình máy nằm ngoài lockfile, nên bạn vẫn phải kiểm tra riêng.

Nên học gì trước

Thứ tự hợp lý là: lockfile và uv sync trước, rồi đến .python-version, sau cùng mới tới --exclude-newer và script có khai báo dependency bên trong. Bài tập tốt nhất là tự làm hỏng rồi tự sửa: xóa .venv, chuyển sang một máy khác hệ điều hành, và kiểm tra xem một lệnh có đủ để chạy lại dự án hay không.

Khi đọc JD của các vị trí FDE, hãy để ý những cụm như “reproducible environments” hay “deploy on customer infrastructure”. Đó là những chỗ kỹ năng này được dùng đến. Trong CV, đừng chỉ ghi “biết uv”; hãy mô tả bạn đã rút việc setup môi trường xuống còn bao nhiêu bước, và kể một lần cụ thể dự án của bạn chạy được trên một máy lạ.

Khách hàng sẽ không nhớ bạn dùng công cụ gì. Họ chỉ nhớ lần đầu clone repo của bạn về, mọi thứ chạy được ngay hay phải mất cả buổi chiều để sửa.

Bài này có hữu ích không?

Dùng cùng trợ lý AIHỏi Claude ↗Hỏi ChatGPT ↗
7 nguồn
Đọc tiếp trên lộ trình · Chặng 1: Nền tảngFull Stack Open của Đại học Helsinki: khoá học miễn phí từ React tới container, và cách FDE nên họcRa đời năm 2019 với một lý do gắn với tin tuyển dụng, khoá học này vẫn là một trong những con đường rẻ nhất để bạn đọc hiểu được codebase JavaScript của khách hàng.