Metadata-Version: 2.4
Name: audiveris-py
Version: 0.1.1
Summary: Python wrapper around the Audiveris CLI for converting PDF/image scores to MusicXML
License-Expression: AGPL-3.0-or-later
Project-URL: Homepage, https://github.com/leonarduk/audiveris-py
Project-URL: Issues, https://github.com/leonarduk/audiveris-py/issues
Project-URL: Audiveris, https://github.com/Audiveris/audiveris
Keywords: audiveris,omr,optical music recognition,musicxml,sheet music
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: End Users/Desktop
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Topic :: Multimedia :: Sound/Audio
Classifier: Topic :: Scientific/Engineering :: Image Recognition
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: test
Requires-Dist: pytest>=7; extra == "test"
Dynamic: license-file

# audiveris-py

[![PyPI](https://img.shields.io/pypi/v/audiveris-py)](https://pypi.org/project/audiveris-py/)
[![CI](https://github.com/leonarduk/audiveris-py/actions/workflows/ci.yml/badge.svg)](https://github.com/leonarduk/audiveris-py/actions/workflows/ci.yml)
[![License: AGPL-3.0](https://img.shields.io/github/license/leonarduk/audiveris-py)](LICENSE)

Thin Python wrapper around the Audiveris command line, for converting PDF or image
scores to MusicXML. It does not reimplement any recognition: it runs
`audiveris -batch -export` and returns the files that run produced.

## Requirements

- An installed [Audiveris](https://github.com/Audiveris/audiveris). It is found via
  `--audiveris`/the `audiveris=` argument, the `AUDIVERIS_BIN` environment variable,
  `audiveris` or `Audiveris` on `PATH`, or the installer's default location
  (`/opt/audiveris/bin/Audiveris`, `C:\Program Files\Audiveris\Audiveris.exe`,
  `/Applications/Audiveris.app/Contents/MacOS/Audiveris`).
- Python 3.9+. No third-party runtime dependencies.

## Install

```sh
pip install audiveris-py
```

Or the latest development version:

```sh
pip install git+https://github.com/leonarduk/audiveris-py.git
```

## Check your setup

```sh
audiveris-py doctor
```

```
[ OK ] Audiveris executable: /opt/audiveris/bin/Audiveris
[ OK ] Audiveris starts: version 5.7.1
[WARN] OCR language data: no *.traineddata in ~/.config/AudiverisLtd/audiveris/tessdata; lyrics and other text will not be recognised
       -> Download e.g. eng.traineddata from https://github.com/tesseract-ocr/tessdata into ~/.config/AudiverisLtd/audiveris/tessdata.
```

It exits non-zero if Audiveris can't be found or won't start. Missing OCR language
files are only a warning: notes are still recognised, text isn't.

`doctor` is reserved as the first argument; to convert a file literally named
`doctor`, pass it as `./doctor`.

## Command line

```sh
audiveris-py score.pdf -o out/
audiveris-py score.pdf -o out/ --sheets 1 2 --uncompressed --timeout 900
```

Each input `name.pdf` is exported as `out/name/name.mxl`, or `out/name/name.mvtN.mxl`
when the book holds several movements. `--uncompressed` also writes a plain
`.musicxml` next to each `.mxl`.

## Library

```python
from audiveris_py import AudiverisError, convert, read_musicxml

try:
    mxl_files = convert("scores/sonata.pdf", "out/", timeout=900)
except AudiverisError as ex:
    print(f"Audiveris failed (exit {ex.returncode}): {ex}")
    print(ex.output)  # full Audiveris console log
    raise SystemExit(1)

for mxl in mxl_files:
    target = mxl.with_suffix(".musicxml")
    target.write_text(read_musicxml(mxl), encoding="utf-8")
    print(f"{mxl} -> {target}")
```

- `convert` returns a list: one `.mxl` per movement (`out/sonata/sonata.mxl`, or
  `sonata.mvtN.mxl` when Audiveris splits the score). Only files written by this
  run are returned, so reusing an output folder is safe.
- `.mxl` is standard compressed MusicXML, so MuseScore, Finale, Sibelius and
  `music21` open it directly. `read_musicxml` is only needed for the plain XML text.
- Options: `sheets=[1, 2]` to process specific pages, `audiveris="/path/to/Audiveris"`
  to skip the lookup, `timeout=` in seconds.
- `convert` raises `AudiverisError` when Audiveris exits non-zero (status 1 = failure,
  2 = timeout, 3 = both) or exports nothing. The error carries `returncode` and the
  full console `output`. A missing input raises `FileNotFoundError`.

For a runnable script that handles a single PDF or a whole folder, see
[`examples/pdf_to_musicxml.py`](examples/pdf_to_musicxml.py).

## Tests

```sh
pip install -e '.[test]'
pytest
```

The unit tests use a fake Audiveris executable. To also run against a real install:

```sh
AUDIVERIS_BIN=/path/to/Audiveris pytest
```

`tests/data/chula.png` is a sample score from the Audiveris project (AGPL-3.0).

## Releasing

Publishing uses PyPI trusted publishing, so no API token is stored in GitHub.

The package version comes from the git tag via `setuptools-scm`; there is no
version to bump in the code.

1. Merge what you want released to `main`.
2. Create a GitHub release with a new tag `v<version>` (e.g. `v0.1.2`) on `main`.
3. The `Publish to PyPI` workflow builds from that tag, checks the built files carry
   that version, and uploads.

Builds from untagged commits get a development version such as `0.1.2.dev3+g1a2b3c4`.
