Metadata-Version: 2.4
Name: imaged
Version: 2026.7.2
Summary: One interface to docker, podman and Apple's container.
Project-URL: Documentation, https://imaged.readthedocs.io/
Project-URL: Homepage, https://github.com/Julian/imaged
Project-URL: Issues, https://github.com/Julian/imaged/issues/
Project-URL: Funding, https://github.com/sponsors/Julian
Project-URL: Source, https://github.com/Julian/imaged
Author-email: Julian Berman <Julian+imaged@GrayVines.com>
License-Expression: MIT
License-File: COPYING
Keywords: anyio,containers,docker,oci,podman
Classifier: Development Status :: 3 - Alpha
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python :: Implementation :: CPython
Requires-Python: >=3.13
Requires-Dist: anyio>=4
Requires-Dist: attrs>=22.2.0
Description-Content-Type: text/x-rst

==========
``imaged``
==========

|PyPI| |Pythons| |CI| |ReadTheDocs|

.. |PyPI| image:: https://img.shields.io/pypi/v/imaged.svg
  :alt: PyPI version
  :target: https://pypi.org/project/imaged/

.. |Pythons| image:: https://img.shields.io/pypi/pyversions/imaged.svg
  :alt: Supported Python versions
  :target: https://pypi.org/project/imaged/

.. |CI| image:: https://github.com/Julian/imaged/workflows/CI/badge.svg
  :alt: Build status
  :target: https://github.com/Julian/imaged/actions?query=workflow%3ACI


.. |ReadTheDocs| image:: https://readthedocs.org/projects/imaged/badge/?version=stable&style=flat
  :alt: ReadTheDocs status
  :target: https://imaged.readthedocs.io/en/stable/

``imaged`` gives you one interface to `docker <https://www.docker.com/>`_,
`podman <https://podman.io/>`_ and `Apple's container
<https://github.com/apple/container>`_.
Start a container, speak to its standard streams, and be told what went wrong
in terms you can branch on.

.. code-block:: python

    from imaged import Engine

    engine = Engine.detect()

    id = await engine.create_pulling_if_needed("alpine", "cat")
    async with engine.start(id) as session:
        await session.send("hello")
        assert await session.receive() == "hello"

Why
---

Every engine reports the same failure differently, and none of them do so
machine readably -- not even over their HTTP APIs.
Working out that an image simply doesn't exist otherwise means matching on
substrings of prose, separately for each engine.
``imaged`` does that once, and raises ``NoSuchImage``.

Each engine is driven via its command line interface, which is the only
mechanism all three have in common, as Apple's container has no HTTP API at
all.
Doing so also leaves the engine to demultiplex container stdio onto real
pipes, rather than leaving you to unpick its framing.

Containers get no networking unless you ask for it, on the theory that
something you are running should have to say so before it can phone home.

`anyio <https://anyio.readthedocs.io/>`_ is the only async dependency, so
this runs unmodified on both asyncio and trio.
Its own test suite runs on both, against all three engines.
