Skip to content

Commit 1e7a37a

Browse files
feat: Replace pip-compile with uv (#4460)
* Update `shell.nix` - Replace pip-compile with uv packages - Pin rust version - Add var to trigger windmill print more info in stdout * Replace `pip-compile` with `uv` (dirty + untested) * Fix arguments passed to uv Some of the flags are included by default in UV and can be safely removed: - --resolver=backtracking - --no-emit-index-url Also uv does not support `--pip-args` and suggests to directly pass args to uv. * Remove extra `dbg!` * Replace 'pip-compile' with 'uv' in Dockerfile * Add fallback option to `pip-compile` (Disabled) * Add `uv` to `docker/DockerfileSlim*` * Add `get_annotation_python` and rename `get_annotation` to `get_annotation_ts` * Add option to fallback to pip-compile Put `# no_uv` on top the file for specific python script Or set `USE_PIP_COMPILE` variable to `true` * Put back `pip-tools` into shell.nix * Make sure lockfile resolves again if `#no_uv` used Add #no_uv to the end of requirements (requirements.in) That way if something breaks for customer, then they put #no_uv and new lockfile will be resolved * Put `pip install pip-tools` in original spot * Fix compilation error * Fix EE compilation error error[E0658]: attributes on expressions are experimental --> windmill-worker/src/python_executor.rs:144:5 | 144 | #[cfg(feature = "enterprise")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #15701 <rust-lang/rust#15701> for more information * Add `no_cache` annotation Will force recalculation of lockfile And block uv from using cached values * Target uv cache to /tmp/windmill/cache * Prohibit uv from managing python * Add uv to DockerfileBackendTests * Pin uv version to 0.4.18 in Dockerfiles * Dont put `#no_uv` in requirements.in Instead postfix hash for requirements.in with `-no_uv` * Push Warning to logs if fallbacked to pip-compile --------- Co-authored-by: Ruben Fiszel <[email protected]>
1 parent 6eb7f8c commit 1e7a37a

14 files changed

+238
-97
lines changed

.github/DockerfileBackendTests

+2-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ RUN wget https://golang.org/dl/go1.21.5.linux-amd64.tar.gz && tar -C /usr/local
4343
ENV PATH="${PATH}:/usr/local/go/bin"
4444
ENV GO_PATH=/usr/local/go/bin/go
4545

46-
RUN curl -LsSf https://astral.sh/uv/install.sh | sh
46+
# Install UV
47+
RUN curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/uv/releases/download/0.4.18/uv-installer.sh | sh
4748

4849
ENV TZ=Etc/UTC
4950

Dockerfile

+3
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,9 @@ RUN set -eux; \
158158
ENV PATH="${PATH}:/usr/local/go/bin"
159159
ENV GO_PATH=/usr/local/go/bin/go
160160

161+
# Install UV
162+
RUN curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/uv/releases/download/0.4.18/uv-installer.sh | sh
163+
161164
RUN curl -sL https://deb.nodesource.com/setup_20.x | bash -
162165
RUN apt-get -y update && apt-get install -y curl nodejs awscli && apt-get clean \
163166
&& rm -rf /var/lib/apt/lists/*

backend/src/main.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ use windmill_worker::{
6767
get_hub_script_content_and_requirements, BUN_BUNDLE_CACHE_DIR, BUN_CACHE_DIR,
6868
BUN_DEPSTAR_CACHE_DIR, DENO_CACHE_DIR, DENO_CACHE_DIR_DEPS, DENO_CACHE_DIR_NPM,
6969
GO_BIN_CACHE_DIR, GO_CACHE_DIR, LOCK_CACHE_DIR, PIP_CACHE_DIR, POWERSHELL_CACHE_DIR,
70-
RUST_CACHE_DIR, TAR_PIP_CACHE_DIR, TMP_LOGS_DIR,
70+
RUST_CACHE_DIR, TAR_PIP_CACHE_DIR, TMP_LOGS_DIR, UV_CACHE_DIR,
7171
};
7272

7373
use crate::monitor::{
@@ -873,6 +873,7 @@ pub async fn run_workers<R: rsmq_async::RsmqConnection + Send + Sync + Clone + '
873873
LOCK_CACHE_DIR,
874874
TMP_LOGS_DIR,
875875
PIP_CACHE_DIR,
876+
UV_CACHE_DIR,
876877
TAR_PIP_CACHE_DIR,
877878
DENO_CACHE_DIR,
878879
DENO_CACHE_DIR_DEPS,

backend/windmill-api/src/jobs.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -4127,7 +4127,7 @@ async fn run_dependencies_job(
41274127
JsonRawValue::from_string("true".to_string()).unwrap(),
41284128
);
41294129
if language == ScriptLang::Bun {
4130-
let annotation = windmill_common::worker::get_annotation(&raw_code);
4130+
let annotation = windmill_common::worker::get_annotation_ts(&raw_code);
41314131
hm.insert(
41324132
"npm_mode".to_string(),
41334133
JsonRawValue::from_string(annotation.npm_mode.to_string()).unwrap(),

backend/windmill-api/src/scripts.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ use windmill_common::{
5353
utils::{
5454
not_found_if_none, paginate, query_elems_from_hub, require_admin, Pagination, StripPath,
5555
},
56-
worker::{get_annotation, to_raw_value},
56+
worker::{get_annotation_ts, to_raw_value},
5757
HUB_BASE_URL,
5858
};
5959
use windmill_git_sync::{handle_deployment_metadata, DeployedObject};
@@ -601,7 +601,7 @@ async fn create_script_internal<'c>(
601601
};
602602

603603
let lang = if &ns.language == &ScriptLang::Bun || &ns.language == &ScriptLang::Bunnative {
604-
let anns = get_annotation(&ns.content);
604+
let anns = get_annotation_ts(&ns.content);
605605
if anns.native_mode {
606606
ScriptLang::Bunnative
607607
} else {

backend/windmill-common/src/worker.rs

+21-3
Original file line numberDiff line numberDiff line change
@@ -303,14 +303,14 @@ fn parse_file<T: FromStr>(path: &str) -> Option<T> {
303303
.flatten()
304304
}
305305

306-
pub struct Annotations {
306+
pub struct TypeScriptAnnotations {
307307
pub npm_mode: bool,
308308
pub nodejs_mode: bool,
309309
pub native_mode: bool,
310310
pub nobundling: bool,
311311
}
312312

313-
pub fn get_annotation(inner_content: &str) -> Annotations {
313+
pub fn get_annotation_ts(inner_content: &str) -> TypeScriptAnnotations {
314314
let annotations = inner_content
315315
.lines()
316316
.take_while(|x| x.starts_with("//"))
@@ -324,7 +324,25 @@ pub fn get_annotation(inner_content: &str) -> Annotations {
324324
let nobundling: bool =
325325
annotations.contains(&"nobundling".to_string()) || nodejs_mode || *DISABLE_BUNDLING;
326326

327-
Annotations { npm_mode, nodejs_mode, native_mode, nobundling }
327+
TypeScriptAnnotations { npm_mode, nodejs_mode, native_mode, nobundling }
328+
}
329+
330+
pub struct PythonAnnotations {
331+
pub no_uv: bool,
332+
pub no_cache: bool,
333+
}
334+
335+
pub fn get_annotation_python(inner_content: &str) -> PythonAnnotations {
336+
let annotations = inner_content
337+
.lines()
338+
.take_while(|x| x.starts_with("#"))
339+
.map(|x| x.to_string().replace("#", "").trim().to_string())
340+
.collect_vec();
341+
342+
let no_uv: bool = annotations.contains(&"no_uv".to_string());
343+
let no_cache: bool = annotations.contains(&"no_cache".to_string());
344+
345+
PythonAnnotations { no_uv, no_cache }
328346
}
329347

330348
pub struct SqlAnnotations {

backend/windmill-worker/src/ansible_executor.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ use crate::{
3333
OccupancyMetrics,
3434
},
3535
handle_child::handle_child,
36-
python_executor::{create_dependencies_dir, handle_python_reqs, pip_compile},
36+
python_executor::{create_dependencies_dir, handle_python_reqs, uv_pip_compile},
3737
AuthedClientBackgroundTask, DISABLE_NSJAIL, DISABLE_NUSER, HOME_ENV, NSJAIL_PATH, PATH_ENV,
3838
TZ_ENV,
3939
};
@@ -80,7 +80,7 @@ async fn handle_ansible_python_deps(
8080
if requirements.is_empty() {
8181
"".to_string()
8282
} else {
83-
pip_compile(
83+
uv_pip_compile(
8484
job_id,
8585
&requirements,
8686
mem_peak,
@@ -90,6 +90,8 @@ async fn handle_ansible_python_deps(
9090
worker_name,
9191
w_id,
9292
&mut Some(occupancy_metrics),
93+
false,
94+
false,
9395
)
9496
.await
9597
.map_err(|e| {

backend/windmill-worker/src/bun_executor.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ use windmill_common::{
4747
get_latest_hash_for_path,
4848
jobs::{QueuedJob, PREPROCESSOR_FAKE_ENTRYPOINT},
4949
scripts::ScriptLang,
50-
worker::{exists_in_cache, get_annotation, save_cache, write_file},
50+
worker::{exists_in_cache, get_annotation_ts, save_cache, write_file},
5151
DB,
5252
};
5353

@@ -663,7 +663,7 @@ pub async fn prebundle_bun_script(
663663
if exists_in_cache(&local_path, &remote_path).await {
664664
return Ok(());
665665
}
666-
let annotation = get_annotation(inner_content);
666+
let annotation = get_annotation_ts(inner_content);
667667
if annotation.nobundling {
668668
return Ok(());
669669
}
@@ -800,7 +800,7 @@ pub async fn handle_bun_job(
800800
new_args: &mut Option<HashMap<String, Box<RawValue>>>,
801801
occupancy_metrics: &mut OccupancyMetrics,
802802
) -> error::Result<Box<RawValue>> {
803-
let mut annotation = windmill_common::worker::get_annotation(inner_content);
803+
let mut annotation = windmill_common::worker::get_annotation_ts(inner_content);
804804

805805
let (mut has_bundle_cache, cache_logs, local_path, remote_path) =
806806
if requirements_o.is_some() && !annotation.nobundling && codebase.is_none() {
@@ -1525,7 +1525,7 @@ pub async fn start_worker(
15251525
let common_bun_proc_envs: HashMap<String, String> =
15261526
get_common_bun_proc_envs(Some(&base_internal_url)).await;
15271527

1528-
let mut annotation = windmill_common::worker::get_annotation(inner_content);
1528+
let mut annotation = windmill_common::worker::get_annotation_ts(inner_content);
15291529

15301530
//TODO: remove this when bun dedicated workers work without issues
15311531
annotation.nodejs_mode = true;

0 commit comments

Comments
 (0)