Skip to content

Commit 24efb1a

Browse files
feat: Add UV utility functions module
Co-Authored-By: Aaron <AJ> Steers <aj@airbyte.io>
1 parent e80c0a3 commit 24efb1a

File tree

1 file changed

+86
-0
lines changed

1 file changed

+86
-0
lines changed

airbyte/_util/uv_util.py

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
"""Utility functions for UV virtual environment management."""
2+
3+
from __future__ import annotations
4+
5+
import os
6+
import subprocess
7+
from pathlib import Path
8+
9+
10+
def run_uv_command(args: list[str], env: dict | None = None, check: bool = False) -> subprocess.CompletedProcess:
11+
"""Run a UV command and return the result.
12+
13+
Args:
14+
args: Command arguments to pass to UV
15+
env: Optional environment variables
16+
check: Whether to raise an exception on non-zero return code
17+
18+
Returns:
19+
CompletedProcess instance with command output
20+
"""
21+
return subprocess.run(
22+
["uv", *args],
23+
capture_output=True,
24+
text=True,
25+
env=env,
26+
check=check,
27+
)
28+
29+
30+
def create_venv(venv_path: Path, with_pip: bool = True) -> None:
31+
"""Create a virtual environment using UV.
32+
33+
Args:
34+
venv_path: Path where the virtual environment should be created
35+
with_pip: Whether to include pip and other seed packages
36+
"""
37+
args = ["venv"]
38+
if with_pip:
39+
args.append("--seed")
40+
args.append(str(venv_path))
41+
run_uv_command(args, check=True)
42+
43+
44+
def install_package(venv_path: Path, pip_url: str) -> None:
45+
"""Install a package into a virtual environment using UV.
46+
47+
Args:
48+
venv_path: Path to the virtual environment
49+
pip_url: Package specification (name, URL, or path) to install
50+
"""
51+
venv_env = get_venv_env(venv_path)
52+
run_uv_command(
53+
["pip", "install", pip_url],
54+
env=venv_env,
55+
check=True,
56+
)
57+
58+
59+
def get_venv_env(venv_path: Path) -> dict:
60+
"""Get environment variables for a virtual environment.
61+
62+
Args:
63+
venv_path: Path to the virtual environment
64+
65+
Returns:
66+
Dict of environment variables
67+
"""
68+
env = os.environ.copy()
69+
env["VIRTUAL_ENV"] = str(venv_path)
70+
env["PATH"] = f"{venv_path}/bin:{os.environ['PATH']}"
71+
return env
72+
73+
74+
def get_executable_path(venv_path: Path, executable: str) -> Path:
75+
"""Get the path to an executable in a virtual environment.
76+
77+
Args:
78+
venv_path: Path to the virtual environment
79+
executable: Name of the executable
80+
81+
Returns:
82+
Path to the executable
83+
"""
84+
bin_dir = "Scripts" if os.name == "nt" else "bin"
85+
suffix = ".exe" if os.name == "nt" else ""
86+
return venv_path / bin_dir / f"{executable}{suffix}"

0 commit comments

Comments
 (0)