feat: add Tesseract.container_info to expose information about running containers in Python API#601
Conversation
When a Tesseract is image-backed (``from_image(...)``), the running
container's name and ID are useful for external tooling: ``docker
stats`` polling, ``docker exec`` debugging, NVML container queries,
``docker logs`` outside the SDK, etc. They're already stored
internally on ``_serve_context``, and used by ``server_logs()`` /
``teardown()`` via that private dict — but downstream callers have
to dig into the private attribute themselves, often with version-
specific fallback paths to older private attrs like ``_container``,
``_service``, or ``_backend``.
Expose them as documented public properties:
- ``Tesseract.container_name`` — current container name, or ``None``
outside the serve window / for non-image Tesseracts.
- ``Tesseract.container_id`` — full container ID (slice ``[:12]`` for
short form), same lifecycle.
Also store the container's ``.id`` in ``_serve_context`` at serve
time so ``container_id`` has something to return. Existing code that
reads ``container_name`` from ``_serve_context`` (``server_logs``,
``teardown``) is unchanged.
Motivated by mosaic-bench's VRAM/RAM polling, which currently does:
for attr in ("_container", "container", "_service", "_backend"):
obj = getattr(t, attr, None)
cid = getattr(obj, "id", None) or getattr(obj, "short_id", None)
...
— scaffolding that becomes a single ``t.container_id`` after this lands.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #601 +/- ##
==========================================
+ Coverage 67.11% 76.83% +9.71%
==========================================
Files 32 32
Lines 4495 4502 +7
Branches 739 741 +2
==========================================
+ Hits 3017 3459 +442
+ Misses 1237 739 -498
- Partials 241 304 +63 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Benchmark ResultsBenchmarks use a no-op Tesseract to measure pure framework overhead. 🚀 0 faster, ✅ No significant performance changes detected. Full results
|
|
Hmm, I wonder if a single method >>> from tesseract_core import Tesseract
>>> tess_image = Tesseract.from_image("foobar")
>>> tess_image.container_info()
RuntimeError: `container_info` is only available for served Tesseracts. Use `tess.serve` or `with tess:` first.
>>> tess_image.serve()
>>> tess_image.container_info()
{"id": ..., "name": ...} # OR Container(...)?!
>>> tess_url = Tesseract.from_url("localhost:5000")
>>> tess_url.container_info()
RuntimeError: `container_info` is only available when using `Tesseract.from_image(...)`. |
…ner_info()
Per review feedback, replace the pair of properties — which returned
``None`` for both "not yet served" and "wrong constructor" cases — with
a single ``container_info()`` method that raises ``RuntimeError`` with
distinct, actionable messages for each case.
- Returns ``{"id": ..., "name": ...}`` matching the plain-dict
convention used elsewhere on ``Tesseract`` (``apply()``, ``health()``,
``openapi_schema``, ``abstract_eval()``).
- Raises when called on a Tesseract created via ``from_url`` or
``from_tesseract_api`` (no Docker container backs it).
- Raises when called on an image-backed Tesseract that isn't currently
being served.
Tests updated to cover the served / pre-serve / post-teardown /
non-image-backed paths.
|
Good call, switching to a single >>> Tesseract.from_url("http://localhost:1234").container_info()
RuntimeError: `container_info` is only available when using `Tesseract.from_image(...)`.
>>> t = Tesseract.from_image("foo:bar"); t.container_info()
RuntimeError: `container_info` is only available for served Tesseracts. Use `tess.serve()` or `with tess:` first.
>>> with t:
... t.container_info()
{"id": "...", "name": "..."}Went with a plain |
…or_non_image_tesseract Use a raw string with an escaped ``.`` for the ``pytest.raises(match=...)`` pattern, and let ruff-format wrap the long ``pytest.raises`` call.
…taclass
Per review feedback, replace the shaped ``{"id": ..., "name": ...}`` dict
with the full ``docker_client.Container`` object via ``Containers.get(...)``.
Each call re-issues a ``docker inspect``, so callers see live ``status``,
``host_port``, ``host_ip``, ``docker_network_ips``, ``exec_run(...)``, and
the raw inspect payload via ``attrs`` — the typical inputs for ``docker
stats`` / ``docker exec`` / NVML / per-container observability.
- Drop the ``container_id`` key added to ``_serve_context``; the
container name in ``_serve_context`` is enough to look the container
up at call time.
- ``container_info()`` keeps the two ``RuntimeError``s for the
non-image and pre-serve cases. A container that disappeared between
``serve()`` and the call now surfaces as
``docker_client.NotFound``, which is the right signal for that case.
- Tests patch ``Containers.get`` to return a stub container and
verify the served call forwards the container name through.
Co-authored-by: Dion Häfner <dion.haefner@simulation.science>
Tesseract.container_info to expose information about running containers in Python API
Relevant issue or PR
n/a — surfaces information already stored in
_serve_contextand consumed internally byserver_logs/teardown.Description of changes
Adds two public properties on
Tesseract:Tesseract.container_name— the running Docker container's name, orNonewhen the Tesseract isn't currently serving (beforeserve(), afterteardown(), or when constructed viafrom_url/from_tesseract_api).Tesseract.container_id— same lifecycle, returns the full container ID (slice[:12]for short form).Also stores the Container object's
.idin_serve_contextat serve time socontainer_idhas something to return. Existing internal use of_serve_context["container_name"](server_logs,teardown) is unchanged.Why. Downstream callers that want to drive
docker stats,docker exec, NVML per-container queries, ordocker logsoutside the SDK currently have to dig through private attributes. A common workaround is to scan multiple attribute names with fallbacks:After this lands that scaffolding collapses to
t.container_id.Testing done
tests/sdk_tests/test_tesseract.py:test_container_id_and_name_set_during_serve— verifies properties areNonebefore serving, take the container's name/ID during, and clear back toNoneafter teardown. Uses the existingmock_servingfixture which already supplies afake_container.id.test_container_id_and_name_none_for_local_tesseract— verifiesfrom_urlTesseracts reportNonefor both properties (no docker container backs them).