Installing dependencies from a lockfile¶
Context¶
Instead of a flat tesseract_requirements.txt, a Tesseract can install its
dependencies from a PEP 751
lockfile (pylock.toml). A lockfile pins every dependency’s exact version, source
index, and artifact hashes, so installing it performs no dependency resolution.
The lockfile is used both for the environment Tesseract.from_source builds and
for container images built with tesseract build.
Point the Tesseract at a lockfile with requirements_file in tesseract_config.yaml:
name: "pylock"
version: "0.1.0"
description: |
Tesseract whose dependencies are installed from a PEP 751 lockfile
(build_config.requirements.requirements_file: pylock.toml) instead of a flat
tesseract_requirements.txt. The committed pylock.toml spans two indexes (PyPI
for numpy, the PyTorch CPU index for torch) with platform markers.
See README.md for how to regenerate the lockfile from _pyproject.toml.
build_config:
requirements:
provider: uv-pip
requirements_file: pylock.toml
Any PEP 751 filename is accepted, either pylock.toml or a named variant like
pylock.prod.toml. The format is inferred from the name.
If you already have a pyproject.toml (or a uv.lock), export a lockfile with
uv export:
$ uv export --format pylock.toml -o pylock.toml
Example Tesseract¶
The example computes a sum with torch and passes it through numpy, so both
packages from the committed lockfile must be installed and importable for apply
to succeed:
# Copyright 2025 Pasteur Labs. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
from pydantic import BaseModel
#
# Schemas
#
class InputSchema(BaseModel):
a: float
b: float
class OutputSchema(BaseModel):
# Sum computed with torch and passed through numpy, so both packages from the
# committed pylock.toml must be installed and importable for apply to succeed.
result: float
#
# Required endpoints
#
def apply(inputs: InputSchema) -> OutputSchema:
import numpy as np
import torch
total = torch.tensor(inputs.a) + torch.tensor(inputs.b)
return OutputSchema(result=float(np.asarray(total).item()))
Then run it as usual:
>>> from tesseract_core import Tesseract
>>> with Tesseract.from_source("examples/pylock/tesseract_api.py") as t:
... print(t.apply({"a": 2.0, "b": 3.0}))
{'result': 5.0}
Or package it as a container image:
$ tesseract build examples/pylock
$ tesseract run pylock apply '{"inputs": {"a": 2.0, "b": 3.0}}'
{"result":5.0}
The Tesseract runtime is installed on top¶
Warning
The lockfile is installed first, then the Tesseract runtime and its dependencies are installed into the same environment. If a runtime dependency requires a version outside the range your lockfile pins, that package is adjusted to satisfy the runtime, so a handful of packages in the final environment may differ from the lockfile. Everything else is installed exactly as pinned. Keep this in mind if you rely on the environment or image matching the lockfile byte-for-byte.
Private and multi-index lockfiles¶
A lockfile records each package’s index location and hashes, but never
credentials. To install from an authenticated index (a private PyPI, an Azure
Artifacts feed, etc.) in a container build, declare the host under
build_config.host_credentials and supply the token at build time with
tesseract build --secret. Tesseract.from_source ignores
host_credentials and installs with uv using your own credentials (for example
~/.netrc, a keyring, or UV_INDEX_* environment variables).