Skip to content

Commit 6ea7abb

Browse files
committed
add system_site_packages arg to tesseract config
1 parent 625a0b4 commit 6ea7abb

8 files changed

Lines changed: 114 additions & 1 deletion

File tree

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# Copyright 2025 Pasteur Labs. All Rights Reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
"""Solve the Poisson equation on a unit square using Firedrake.
5+
6+
Firedrake is NOT listed in tesseract_requirements.txt — it's only available
7+
because system_site_packages is enabled and Firedrake is pre-installed in the
8+
base image.
9+
"""
10+
11+
from pydantic import BaseModel, Field
12+
13+
14+
class InputSchema(BaseModel):
15+
mesh_resolution: int = Field(
16+
description="Number of cells along each edge of the unit square mesh.",
17+
ge=1,
18+
)
19+
20+
21+
class OutputSchema(BaseModel):
22+
num_dofs: int = Field(description="Number of degrees of freedom in the solution.")
23+
l2_error: float = Field(
24+
description="L2 norm of the error against the exact solution."
25+
)
26+
27+
28+
def apply(inputs: InputSchema) -> OutputSchema:
29+
"""Solve -laplacian(u) = f on the unit square with known exact solution."""
30+
from firedrake import (
31+
DirichletBC,
32+
Function,
33+
FunctionSpace,
34+
SpatialCoordinate,
35+
TestFunction,
36+
TrialFunction,
37+
UnitSquareMesh,
38+
dx,
39+
errornorm,
40+
grad,
41+
inner,
42+
pi,
43+
sin,
44+
solve,
45+
)
46+
47+
mesh = UnitSquareMesh(inputs.mesh_resolution, inputs.mesh_resolution)
48+
V = FunctionSpace(mesh, "CG", 1)
49+
50+
u = TrialFunction(V)
51+
v = TestFunction(V)
52+
53+
x, y = SpatialCoordinate(mesh)
54+
exact = sin(pi * x) * sin(pi * y)
55+
f = 2 * pi**2 * sin(pi * x) * sin(pi * y)
56+
57+
a = inner(grad(u), grad(v)) * dx
58+
L = f * v * dx
59+
60+
bc = DirichletBC(V, 0, "on_boundary")
61+
62+
u_h = Function(V)
63+
solve(a == L, u_h, bcs=bc)
64+
65+
l2_err = errornorm(exact, u_h, norm_type="L2")
66+
67+
return OutputSchema(num_dofs=V.dof_count, l2_error=l2_err)
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
name: "system_site_packages"
2+
version: "0.1.0"
3+
description: |
4+
Tesseract that uses system_site_packages to access Firedrake,
5+
a finite element library pre-installed in the base image.
6+
7+
build_config:
8+
base_image: "firedrakeproject/firedrake:2026.4.0"
9+
system_site_packages: true
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# No extra requirements — Firedrake is provided by the base image
2+
# via system_site_packages: true in tesseract_config.yaml.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"endpoint": "apply",
3+
"expected_outputs": {
4+
"num_dofs": 25,
5+
"l2_error": 0.07907545425172705
6+
},
7+
"expected_exception": null,
8+
"expected_exception_regex": null,
9+
"atol": 1e-4,
10+
"rtol": 1e-4,
11+
"payload": {
12+
"inputs": {
13+
"mesh_resolution": 4
14+
}
15+
}
16+
}

tesseract_core/sdk/api_parse.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,15 @@ class TesseractBuildConfig(BaseModel, validate_assignment=True):
133133
),
134134
)
135135

136+
system_site_packages: bool = Field(
137+
False,
138+
description=(
139+
"If True, create the Python virtual environment with --system-site-packages. "
140+
"This allows the venv to access packages pre-installed in the base image "
141+
"(e.g., Firedrake, FEniCS, OpenFOAM)."
142+
),
143+
)
144+
136145
requirements: PythonRequirements = PipRequirements(provider="python-pip")
137146

138147
model_config = ConfigDict(extra="forbid")

tesseract_core/sdk/templates/Dockerfile.base

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ COPY {{ tesseract_source_directory }}/{{ config.build_config.requirements._filen
4646
COPY {{ config.build_config.requirements._build_script }} ./
4747
COPY local_requirements/ ./local_requirements
4848

49+
{% if config.build_config.system_site_packages %}
50+
ENV TESSERACT_SYSTEM_SITE_PACKAGES=1
51+
{% endif %}
52+
4953
# Build a python venv from python provider build scripts.
5054
# The build script has to create a venv at /python-env
5155
RUN --mount=type=cache,target=/root/.cache/uv {% if use_ssh_mount %}--mount=type=ssh{% endif %} bash {{ config.build_config.requirements._build_script }}

tesseract_core/sdk/templates/build_pip_venv.sh

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,12 @@
55

66
set -e # Exit immediately if a command exits with a non-zero status
77

8-
uv venv /python-env
8+
SYSTEM_SITE_PACKAGES_FLAG=""
9+
if [ "${TESSERACT_SYSTEM_SITE_PACKAGES:-0}" = "1" ]; then
10+
SYSTEM_SITE_PACKAGES_FLAG="--system-site-packages"
11+
fi
12+
13+
uv venv $SYSTEM_SITE_PACKAGES_FLAG /python-env
914
source /python-env/bin/activate
1015

1116
# Collect dependencies

tests/endtoend_tests/test_examples.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ class Config:
108108
),
109109
"metrics": Config(test_with_random_inputs=True),
110110
"qp_solve": Config(),
111+
"system_site_packages": Config(),
111112
"tesseractreference": Config(), # Can't test requests standalone; needs target Tesseract. Covered in separate test.
112113
"userhandling": Config(),
113114
}

0 commit comments

Comments
 (0)