Metadata-Version: 2.4
Name: tesseract-core
Version: 1.8.2
Summary: A toolkit for universal, autodiff-native software components.
Project-URL: Homepage, https://github.com/pasteurlabs/tesseract-core
Project-URL: Documentation, https://docs.pasteurlabs.ai/projects/tesseract-core/latest
Author-email: "The Tesseract team @ Pasteur Labs + OSS contributors" <info@simulation.science>
License: Apache-2.0
License-File: LICENSE
Requires-Python: <3.15,>=3.10
Requires-Dist: jinja2
Requires-Dist: numpy
Requires-Dist: orjson
Requires-Dist: packaging
Requires-Dist: pip
Requires-Dist: pybase64
Requires-Dist: pydantic
Requires-Dist: pyyaml
Requires-Dist: requests>=2.32.4
Requires-Dist: rich
Requires-Dist: typer
Provides-Extra: dev
Requires-Dist: aiobotocore>=2.19.0; extra == 'dev'
Requires-Dist: autodoc-pydantic; extra == 'dev'
Requires-Dist: click<=8.3.3,>=8.1; extra == 'dev'
Requires-Dist: debugpy<=1.8.20,>=1.8.14; extra == 'dev'
Requires-Dist: docker; extra == 'dev'
Requires-Dist: fastapi; extra == 'dev'
Requires-Dist: fastapi<=0.136.1,>=0.115; extra == 'dev'
Requires-Dist: fsspec[http,s3]<=2026.4.0,>=2024.12; extra == 'dev'
Requires-Dist: furo; extra == 'dev'
Requires-Dist: httpx; extra == 'dev'
Requires-Dist: mlflow-skinny<=3.11.1,>=3.7.0; extra == 'dev'
Requires-Dist: moto[server]; extra == 'dev'
Requires-Dist: myst-nb; extra == 'dev'
Requires-Dist: numpy; extra == 'dev'
Requires-Dist: numpy<=2.4.4,>=1.26; extra == 'dev'
Requires-Dist: orjson<=3.11.8,>=3.10; extra == 'dev'
Requires-Dist: pre-commit; extra == 'dev'
Requires-Dist: pybase64<=1.4.3,>=1.4; extra == 'dev'
Requires-Dist: pydantic<=2.13.3,>=2.10; extra == 'dev'
Requires-Dist: pytest; extra == 'dev'
Requires-Dist: pytest-benchmark; extra == 'dev'
Requires-Dist: pytest-cov; extra == 'dev'
Requires-Dist: pytest-mock; extra == 'dev'
Requires-Dist: pytest-timeout; extra == 'dev'
Requires-Dist: requests<=2.33.1,>=2.32.4; extra == 'dev'
Requires-Dist: sphinx-autodoc-typehints; extra == 'dev'
Requires-Dist: sphinx-click; extra == 'dev'
Requires-Dist: sphinx-copybutton; extra == 'dev'
Requires-Dist: sphinx-design; extra == 'dev'
Requires-Dist: sphinx<9; extra == 'dev'
Requires-Dist: sphinxext-opengraph; extra == 'dev'
Requires-Dist: typeguard; extra == 'dev'
Requires-Dist: typer<=0.25.1,>=0.15; extra == 'dev'
Requires-Dist: uvicorn<=0.46.0,>=0.34; extra == 'dev'
Provides-Extra: docs
Requires-Dist: autodoc-pydantic; extra == 'docs'
Requires-Dist: click<=8.3.3,>=8.1; extra == 'docs'
Requires-Dist: debugpy<=1.8.20,>=1.8.14; extra == 'docs'
Requires-Dist: fastapi<=0.136.1,>=0.115; extra == 'docs'
Requires-Dist: fsspec[http,s3]<=2026.4.0,>=2024.12; extra == 'docs'
Requires-Dist: furo; extra == 'docs'
Requires-Dist: mlflow-skinny<=3.11.1,>=3.7.0; extra == 'docs'
Requires-Dist: myst-nb; extra == 'docs'
Requires-Dist: numpy<=2.4.4,>=1.26; extra == 'docs'
Requires-Dist: orjson<=3.11.8,>=3.10; extra == 'docs'
Requires-Dist: pybase64<=1.4.3,>=1.4; extra == 'docs'
Requires-Dist: pydantic<=2.13.3,>=2.10; extra == 'docs'
Requires-Dist: requests<=2.33.1,>=2.32.4; extra == 'docs'
Requires-Dist: sphinx-autodoc-typehints; extra == 'docs'
Requires-Dist: sphinx-click; extra == 'docs'
Requires-Dist: sphinx-copybutton; extra == 'docs'
Requires-Dist: sphinx-design; extra == 'docs'
Requires-Dist: sphinx<9; extra == 'docs'
Requires-Dist: sphinxext-opengraph; extra == 'docs'
Requires-Dist: typer<=0.25.1,>=0.15; extra == 'docs'
Requires-Dist: uvicorn<=0.46.0,>=0.34; extra == 'docs'
Provides-Extra: runtime
Requires-Dist: click<=8.3.3,>=8.1; extra == 'runtime'
Requires-Dist: debugpy<=1.8.20,>=1.8.14; extra == 'runtime'
Requires-Dist: fastapi<=0.136.1,>=0.115; extra == 'runtime'
Requires-Dist: fsspec[http,s3]<=2026.4.0,>=2024.12; extra == 'runtime'
Requires-Dist: mlflow-skinny<=3.11.1,>=3.7.0; extra == 'runtime'
Requires-Dist: numpy<=2.4.4,>=1.26; extra == 'runtime'
Requires-Dist: orjson<=3.11.8,>=3.10; extra == 'runtime'
Requires-Dist: pybase64<=1.4.3,>=1.4; extra == 'runtime'
Requires-Dist: pydantic<=2.13.3,>=2.10; extra == 'runtime'
Requires-Dist: requests<=2.33.1,>=2.32.4; extra == 'runtime'
Requires-Dist: typer<=0.25.1,>=0.15; extra == 'runtime'
Requires-Dist: uvicorn<=0.46.0,>=0.34; extra == 'runtime'
Description-Content-Type: text/markdown

<picture>
  <source media="(prefers-color-scheme: dark)" srcset="https://github.com/pasteurlabs/tesseract-core/blob/main/docs/static/logo-dark.png" width="128" align="right">
  <img alt="" src="https://github.com/pasteurlabs/tesseract-core/blob/main/docs/static/logo-light.png" width="128" align="right">
</picture>

### Tesseract Core

Universal, autodiff-native software components for [Simulation Intelligence](https://docs.pasteurlabs.ai/projects/tesseract-core/latest/content/misc/faq.html#what-is-simulation-intelligence) 📦

[Read the docs](https://docs.pasteurlabs.ai/projects/tesseract-core/latest/) |
[Showcases & tutorials](https://si-tesseract.discourse.group/c/showcase/11) |
[Report an issue](https://github.com/pasteurlabs/tesseract-core/issues) |
[Community forum](https://si-tesseract.discourse.group/) |
[Contribute](https://github.com/pasteurlabs/tesseract-core/blob/main/CONTRIBUTING.md)

---

[![DOI](https://joss.theoj.org/papers/10.21105/joss.08385/status.svg)](https://doi.org/10.21105/joss.08385)
[![SciPy](https://img.shields.io/badge/SciPy-2025-blue)](https://proceedings.scipy.org/articles/kvfm5762)

## The problem

**Real-world scientific workflows span multiple tools, languages, and computing environments.** You might have a mesh generator in C++, a solver in Julia, and post-processing in Python. Getting these to work together is painful. Getting gradients to flow through them for optimization is nearly impossible.

Existing autodiff frameworks work great within a single codebase, but fall short when your pipeline crosses framework boundaries or includes legacy tools.

## The solution

Tesseract packages scientific software into **self-contained, portable components** that:

- **Run anywhere** — Local machines, cloud, HPC clusters. Same container, same results.
- **Expose clean interfaces** — CLI, REST API, and Python SDK. No more deciphering undocumented scripts.
- **Propagate gradients** — Each component can expose derivatives, enabling end-to-end optimization across heterogeneous pipelines.
- **Self-document** — Schemas, types, and API docs are generated automatically.

## Who is this for?

- **Researchers** interfacing with (differentiable) simulators or probabilistic models, or who need to combine tools from different ecosystems.
- **R&D engineers** packaging research code for use by others, without spending weeks on DevOps.
- **Platform engineers** deploying scientific workloads at scale with consistent interfaces and dependency isolation.

## Example: Shape optimization across tools

<a href="https://si-tesseract.discourse.group/t/parametric-shape-optimization-of-rocket-fins-with-ansys-spaceclaim-pyansys-and-tesseract/109">
<img src="https://github.com/pasteurlabs/tesseract-core/blob/main/docs/img/bracket_final.png" width="200" align="right" alt="Topology-optimized bracket produced by a differentiable Tesseract pipeline" title="Topology-optimized bracket produced by a multi-tool differentiable Tesseract pipeline.">
</a>

The [rocket fin optimization case study](https://si-tesseract.discourse.group/t/parametric-shape-optimization-of-rocket-fins-with-ansys-spaceclaim-pyansys-and-tesseract/109) combines three Tesseracts:

```
[SpaceClaim geometry] → [Mesh + SDF] → [PyMAPDL FEA solver]
         ↑                                      |
         └──────── gradients flow back ─────────┘
```

Each component uses a different differentiation strategy (analytic adjoints, finite differences, JAX autodiff), yet they compose into a single optimizable pipeline that [is one `jax.grad` call away](https://github.com/pasteurlabs/tesseract-jax) from end-to-end gradients.

> [!TIP]
> More examples in the [example gallery](https://docs.pasteurlabs.ai/projects/tesseract-core/latest/content/examples/example_gallery.html) and [community showcases](https://si-tesseract.discourse.group/c/showcase/11).

## Quick start

<p align="center">
<img src="https://github.com/pasteurlabs/tesseract-core/blob/main/docs/img/demo.gif" width="720" alt="Demo: install, build, and run a Tesseract in under a minute">
<br>
<em>Getting started: install, build an example, and run it.</em>
</p>

> [!NOTE]
> Requires [Docker](https://docs.docker.com/engine/install/) and Python 3.10+.

**CLI:**

```bash
# Install Tesseract Core
$ pip install tesseract-core

# Create a new project in the current directory
$ tesseract init --name my-tesseract

# Edit `tesseract_api.py`, or download an example
$ curl -so ./tesseract_api.py https://raw.githubusercontent.com/pasteurlabs/tesseract-core/main/examples/vectoradd/tesseract_api.py

# Build it into a container
$ tesseract build .

# Run it
$ tesseract run my-tesseract apply '{"inputs": {"a": [1, 2, 3], "b": [10, 20, 30]}}'
# → {"result": [11, 22, 33]}

# Compute the Jacobian
$ tesseract run my-tesseract jacobian '{"inputs": {"a": [1, 2, 3], "b": [10, 20, 30]}, "jac_inputs": ["a"], "jac_outputs": ["result"]}'
# → {"result": {"a": [[1, 0, 0], [0, 1, 0], [0, 0, 1]]}}
```

**Python SDK:**

```python
from tesseract_core import Tesseract

with Tesseract.from_image("my-tesseract") as t:
    result = t.apply({"a": [1, 2, 3], "b": [10, 20, 30]})
    jac = t.jacobian({"a": [1, 2, 3], "b": [10, 20, 30]}, jac_inputs=["a"], jac_outputs=["result"])
```

## Core features

- **Containerized** — Docker-based packaging ensures reproducibility and dependency isolation.
- **Multi-interface** — Use the same components via CLI, REST API, and Python SDK.
- **Differentiable** — First-class support for Jacobians, JVPs, and VJPs across component and network boundaries.
- **Schema-validated** — Pydantic models define explicit input/output contracts.
- **Language-agnostic** — Wrap Python, Julia, C++, [Fortran](https://docs.pasteurlabs.ai/projects/tesseract-core/latest/content/examples/building-blocks/fortran.html), or any executable behind a thin Python API.
- **Self-documenting** — Auto-generated API docs and schemas for every Tesseract (`tesseract apidoc <name>`).

<p align="center">
<img src="https://github.com/pasteurlabs/tesseract-core/blob/main/docs/img/apidoc-screenshot.png" width="600" alt="Auto-generated API documentation for a Tesseract">
<br>
<em>Auto-generated API documentation (<code>tesseract apidoc</code>).</em>
</p>

## The Ecosystem

- **[Tesseract Core](https://github.com/pasteurlabs/tesseract-core)** — CLI, Python SDK, and runtime (this repo).
- **[Tesseract-JAX](https://github.com/pasteurlabs/tesseract-jax)** — Embed Tesseracts as JAX primitives into end-to-end differentiable JAX programs.
- **[Tesseract-Streamlit](https://github.com/pasteurlabs/tesseract-streamlit)** — Auto-generate interactive web apps from Tesseracts.

## Learn more

- [Documentation](https://docs.pasteurlabs.ai/projects/tesseract-core/latest/)
- [Creating your first Tesseract](https://docs.pasteurlabs.ai/projects/tesseract-core/latest/content/creating-tesseracts/create.html)
- [Differentiable programming guide](https://docs.pasteurlabs.ai/projects/tesseract-core/latest/content/introduction/differentiable-programming.html)
- [Design patterns](https://docs.pasteurlabs.ai/projects/tesseract-core/latest/content/creating-tesseracts/design-patterns.html)
- [Example gallery](https://docs.pasteurlabs.ai/projects/tesseract-core/latest/content/examples/example_gallery.html)

## Citing Tesseract

If you use Tesseract in your research, please cite:

```bibtex
@article{TesseractCore,
  doi = {10.21105/joss.08385},
  url = {https://doi.org/10.21105/joss.08385},
  year = {2025},
  publisher = {The Open Journal},
  volume = {10},
  number = {111},
  pages = {8385},
  author = {Häfner, Dion and Lavin, Alexander},
  title = {Tesseract Core: Universal, autodiff-native software components for Simulation Intelligence},
  journal = {Journal of Open Source Software}
}
```

## License

Tesseract Core is licensed under the [Apache License 2.0](https://github.com/pasteurlabs/tesseract-core/blob/main/LICENSE) and is free to use, modify, and distribute (under the terms of the license).

Tesseract is a registered trademark of Pasteur Labs, Inc. and may not be used without permission.
