Tips for Defining Tesseract APIs¶
Advanced Pydantic features¶
Warning
Pydantic V2 metadata and transformations like AfterValidator, Field, model_validator, and field_validator are generally supported for all inputs named inputs (first argument of various endpoints), and outputs of apply. They are silently stripped in all other cases (except in abstract_eval).
Tesseract uses Pydantic to define and validate endpoint signatures. Pydantic is a powerful library that allows for complex type definition and validation, but not all of its features are supported by Tesseract.
One core feature of Tesseract is that only the input and output schema for apply is user-specified, while all other endpoint schemas are inferred from them, which cannot preserve all features of the original schema.
Tesseract supports almost all Pydantic features for endpoint inputs named inputs (that is, the first argument to apply, jacobian, jacobian_vector_product, vector_jacobian_product):
class InputSchema(BaseModel):
# ✅ Field metadata + validators
field: int = Field(..., description="Field description", ge=0, le=10)
# ✅ Nested models
nested: NestedModel
# ✅ Default values
default: int = 10
# ✅ Union types
union: Union[int, str]
another_union: int | str
# ✅ Generic containers
list_of_ints: List[int]
dict_of_strs: Dict[str, str]
# ✅ Field validators
validated_field: Annotated[int, AfterValidator(my_validator)]
# ✅ Model validators
@model_validator
def check_something(self):
if self.field > 10:
raise ValueError("Field must be less than 10")
return self
# ❌ Recursive models, will raise a build error
itsame: "InputSchema"
# ❌ Custom types with __get_pydantic_core_schema__, will raise runtime errors
custom: CustomType
Note
In case you run into issues with Pydantic features not listed here, please open an issue.
Building Tesseracts with private dependencies¶
In case you have some dependencies in tesseract_requirements.txt for which you need to
ssh into a server (e.g., private repositories which you specify via “git+ssh://…”),
you can make your ssh agent available to tesseract build with the option
--forward-ssh-agent. Alternatively you can use pip download to download a dependency
to the machine that builds the Tesseract.
Customizing the build process¶
The build_config section of tesseract_config.yaml controls how the Tesseract image is built. Common reasons to customize it:
Your code needs system libraries (e.g.,
gfortran,libgomp1) — useextra_packagesto install them viaapt-get.You need a specific Python version or GPU drivers — override
base_image(must be Debian-based).You’re deploying to a different architecture (e.g., ARM64 on AWS Graviton) — set
target_platform.Your Tesseract needs data files at runtime (model weights, config files) — use
package_datato copy them into the image.None of the above cover your case — use
custom_build_stepsto inject arbitrary Dockerfile commands. See the Dockerfile template for where these are injected.
See also
For the full list of options and their defaults, see the Configuration reference.
For worked examples, see the Package Data, Pyvista on ARM64, and Fortran Integration building blocks.
Creating a Tesseract from a Python package¶
Sometimes it is useful to create a Tesseract from an already-existing
Python package. In order to do so, you can run tesseract init in the root folder of
your package (i.e., where setup.py and requirements.txt would be). Import your package
as needed in tesseract_api.py, and specify the dependencies you need at runtime in
tesseract_requirements.txt.