Metadata-Version: 2.4
Name: rna
Version: 1.0.0
Summary: The abstractions you keep rewriting, written once: design patterns and polymorphism as importable code, one plotting API across backends, and layered typed configuration
Project-URL: Homepage, https://gitlab.com/dboe/rna
Project-URL: Documentation, https://dboe.gitlab.io/rna
Project-URL: Repository, https://gitlab.com/dboe/rna
Project-URL: Issues, https://gitlab.com/dboe/rna/-/issues/
Project-URL: Changelog, https://gitlab.com/dboe/rna/-/blob/master/CHANGELOG.md
Author-email: Daniel Böckenhoff <dboe@ipp.mpg.de>
Maintainer-email: Daniel Böckenhoff <dboe@ipp.mpg.de>
License-Expression: MIT
License-File: AUTHORS.rst
License-File: LICENSE.rst
Keywords: argparse,backend,logging,matplotlib,path,plotting
Classifier: Development Status :: 5 - Production/Stable
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Python: >=3.11
Provides-Extra: app
Requires-Dist: hydra-core; extra == 'app'
Requires-Dist: omegaconf; extra == 'app'
Provides-Extra: categorical
Requires-Dist: scikit-learn; extra == 'categorical'
Provides-Extra: config
Requires-Dist: pydantic-settings[yaml]>=2.8; extra == 'config'
Requires-Dist: pydantic>=2.10; extra == 'config'
Provides-Extra: full
Requires-Dist: hydra-core; extra == 'full'
Requires-Dist: matplotlib; extra == 'full'
Requires-Dist: more-itertools; extra == 'full'
Requires-Dist: numpy>=1.22; extra == 'full'
Requires-Dist: omegaconf; extra == 'full'
Requires-Dist: pydantic-settings[yaml]>=2.8; extra == 'full'
Requires-Dist: pydantic>=2.10; extra == 'full'
Requires-Dist: pyvista>=0.44; extra == 'full'
Requires-Dist: scikit-learn; extra == 'full'
Provides-Extra: plotting
Requires-Dist: matplotlib; extra == 'plotting'
Requires-Dist: more-itertools; extra == 'plotting'
Requires-Dist: numpy>=1.22; extra == 'plotting'
Provides-Extra: pyvista
Requires-Dist: pyvista>=0.44; extra == 'pyvista'
Description-Content-Type: text/x-rst

===
rna
===

..
    [shields-start]

|pypi| |python| |license| |pipeline| |release| |coverage| |docs| |pre-commit|

.. |pypi| image:: https://img.shields.io/pypi/v/rna.svg
    :target: https://pypi.org/project/rna/
    :alt: Latest release on PyPI
.. |python| image:: https://img.shields.io/pypi/pyversions/rna.svg
    :target: https://pypi.org/project/rna/
    :alt: Supported python versions
.. |license| image:: https://img.shields.io/pypi/l/rna.svg
    :target: https://gitlab.com/dboe/rna/-/blob/master/LICENSE.rst
    :alt: MIT licensed
.. |pipeline| image:: https://gitlab.com/dboe/rna/badges/master/pipeline.svg
    :target: https://gitlab.com/dboe/rna/-/pipelines/latest
    :alt: Pipeline status
.. |release| image:: https://gitlab.com/dboe/rna/-/badges/release.svg
    :target: https://gitlab.com/dboe/rna/-/releases
    :alt: Latest release tag
.. |coverage| image:: https://gitlab.com/dboe/rna/badges/master/coverage.svg
    :target: https://gitlab.com/dboe/rna/commits/master
    :alt: Test coverage
.. |docs| image:: https://img.shields.io/website-up-down-green-red/https/dboe.gitlab.io/rna.svg?label=docs
    :target: https://dboe.gitlab.io/rna
    :alt: Documentation
.. |pre-commit| image:: https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white
    :target: https://github.com/pre-commit/pre-commit
    :alt: pre-commit

..
    [shields-end]

..
    [overview-start]

**The abstractions you keep rewriting, written once.** rna packages the design
patterns and polymorphism helpers every grown codebase re-invents — strategy,
backend, composite, decorator, singleton, switch, attribute links, and
``Storable``/``Plottable`` mixins that turn one ``_save_<ext>`` method into full
save/load dispatch. On top of that base it ships the proof the patterns carry
weight: one plotting API over matplotlib and pyvista, and configuration that
layers. The core has no required dependencies at all.

..
    [overview-end]

.. code-block:: python

    import numpy as np
    import rna.plotting

    vertices = np.array([[0.0, 0, 0], [1, 0, 0], [1, 1, 0], [0, 1, 0]])
    faces = np.array([[0, 1, 2], [0, 2, 3]])

    axes = rna.plotting.add_subplot(dim=3)                     # matplotlib, pyvista, ...
    artist = rna.plotting.plot_mesh(axes, vertices, faces, color=[0.2, 0.8], cmap="plasma")
    rna.plotting.set_colorbar(axes, artist)
    rna.plotting.save("mesh.png")

That is the whole program on either backend, and it is rna's own patterns at work: the
renderer behind those verbs is a *strategy*, so ``rna.plotting.use("pyvista")`` swaps it
without touching a line, and the default — ``"auto"`` — makes the choice itself once a
mesh gets big enough to need a GPU.

Why rna
-------

..
    [why-start]

**Patterns, tested once.** Strategy, backend, composite, decorator, singleton, switch
and symlink-like attribute links. The classic design patterns live in books and blog
posts — as code you are expected to retype — and rna is the package that ships them
instead: base classes with doctests, in place of the fourth hand-rolled registry in
your codebase.

**Polymorphism you declare in one method.** Subclass ``Storable``, implement
``_save_json``, and your object has ``save``/``load`` with extension dispatch, path
expansion and in-memory buffers; the same move gives any class a backend-agnostic
``plot``. Try finding that on PyPI — this is the piece rna exists for.

**One plotting API is the patterns' proof.** ``matplotlib`` is right until a mesh has a
hundred thousand faces, and then it is very wrong. Built on the strategy pattern above,
rna puts both it and ``pyvista`` behind fifteen verbs (``add_subplot``, ``plot_mesh``,
``set_colorbar``, ``save``, …), so switching is a one-line decision instead of a
rewrite. Those fifteen names are the package's semver promise — see `the plotting guide
<https://dboe.gitlab.io/rna/lib/usage/plotting.html>`_.

**Nothing you did not ask for.** The core installs zero dependencies. numpy, matplotlib,
pydantic, hydra and pyvista each live behind an extra, so a library that only wants
``rna.path`` and ``rna.log`` pays for neither a plotting stack nor a settings framework.

**Configuration that actually layers.** Packaged defaults, then a user file, then
environment variables, validated by pydantic, with ``${...}`` references resolved across
all three. And, deliberately, without pinning ``antlr4`` the way hydra does.

..
    [why-end]

Features
~~~~~~~~

..
    [features-start]

* ``rna.pattern`` — reusable design-pattern implementations: strategy, backend,
  composite, decorator, singleton, switch, attribute links
* ``rna.polymorphism`` — ``Storable`` and ``Plottable`` mixins: implement
  ``_save_<ext>`` and get extension dispatch, ``save``/``load`` and buffers for free
* ``rna.plotting`` — a multi-backend plotting facade: matplotlib, pyvista, or an
  automatic choice between them behind one API
* ``rna.config`` — layered, typed package settings on pydantic-settings, plus composed
  application config for hydra-based CLIs (``rna.config.app``)
* ``rna.log`` — colour-formatted logging with an optional tqdm progress bar
* ``rna.path`` — ``pathlib``-based path utilities that resolve ``~``, symlinks and ``..``
* ``rna.parsing`` — ``argparse`` parent parser that wires up logging from the command line
* ``rna.process`` — run a shell command with its output streamed into a logger

..
    [features-end]

Installation
~~~~~~~~~~~~

..
    [install-start]

.. code-block:: shell

    pip install rna

..
    [install-end]

..
    [extras-start]

The core is dependency-free; each subpackage that needs more declares an extra:

=========================  =======================================  ==========================
Extra                      Pulls in                                 Needed for
=========================  =======================================  ==========================
``rna[plotting]``          numpy, matplotlib, more-itertools        ``rna.plotting``
``rna[pyvista]``           pyvista (and VTK, ~68 MB)                the GPU plotting backend
``rna[config]``            pydantic, pydantic-settings              ``rna.config``
``rna[app]``               hydra-core, omegaconf                    ``rna.config.app``
``rna[categorical]``       scikit-learn                             categorical plot colours
``rna[full]``              all of the above                         everything
=========================  =======================================  ==========================

..
    [extras-end]

Usage
~~~~~

..
    [usage-start]

.. code-block:: python

    import json
    import rna.polymorphism

    class Run(rna.polymorphism.Storable):
        def __init__(self, samples):
            self.samples = samples

        def _save_json(self, path, **kwargs):
            with open(path, "w") as file_:
                json.dump(self.samples, file_)

        @classmethod
        def _load_json(cls, path, **kwargs):
            with open(path) as file_:
                return cls(json.load(file_))

    Run([1, 2, 3]).save("~/runs", "2026-08", "latest.json")   # dispatch on the extension,
    run = Run.load("~/runs/2026-08/latest.json")              # "~" resolved, parents created

One method per format is all you write; ``save``/``load`` grow extension dispatch, path
resolution, buffers and a ``NotImplementedError`` that names the method missing for a
format you did not implement.

..
    [usage-end]

The `usage guide <https://dboe.gitlab.io/rna/lib/usage/index.html>`_ walks through every
subpackage with runnable examples; the `API reference
<https://dboe.gitlab.io/rna/api/_autosummary/rna.html>`_ has the details.

Resources
~~~~~~~~~

..
    [resources-start]

- Documentation: https://dboe.gitlab.io/rna
- Source code: https://gitlab.com/dboe/rna
- Bug reports: https://gitlab.com/dboe/rna/-/issues/
- Changelog: https://gitlab.com/dboe/rna/-/blob/master/CHANGELOG.md
- PyPI: https://pypi.org/project/rna/

..
    [resources-end]

Contributing
~~~~~~~~~~~~

``pixi run help`` lists every task in the repository; ``pixi run test`` runs the suite and
``pixi run docs`` builds and opens these pages. The `contributing guide
<https://dboe.gitlab.io/rna/contributing/index.html>`_ covers the branching model, how a
release is cut, and what the pipeline checks before a merge.

License
~~~~~~~

MIT — see `LICENSE.rst <https://gitlab.com/dboe/rna/-/blob/master/LICENSE.rst>`_.
