Metadata-Version: 2.4
Name: djmux
Version: 1.0.1
Summary: Shared DataJoint connection and multi-prefix schema activation
Project-URL: Homepage, https://github.com/larsrollik/djmux
Project-URL: Documentation, https://larsrollik.github.io/djmux/
Project-URL: Issue Tracker, https://github.com/larsrollik/djmux/issues
Author-email: "Lars B. Rollik" <code@rollik.me>
License: 
        BSD 3-Clause License
        
        Copyright (c) 2026-present, Lars B. Rollik
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
        modification, are permitted provided that the following conditions are met:
        
        1. Redistributions of source code must retain the above copyright notice,
           this list of conditions and the following disclaimer.
        
        2. Redistributions in binary form must reproduce the above copyright notice,
           this list of conditions and the following disclaimer in the documentation
           and/or other materials provided with the distribution.
        
        3. Neither the name of the copyright holder nor the names of its contributors
           may be used to endorse or promote products derived from this software
           without specific prior written permission.
        
        THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
        AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
        LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
        CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
        SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
        INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
        CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
        POSSIBILITY OF SUCH DAMAGE.
License-File: LICENSE
Requires-Python: >=3.10
Requires-Dist: datajoint>=0.14
Requires-Dist: pyyaml>=6.0
Provides-Extra: dev
Requires-Dist: commitizen; extra == 'dev'
Requires-Dist: mypy; extra == 'dev'
Requires-Dist: pre-commit; extra == 'dev'
Requires-Dist: pytest-cov; extra == 'dev'
Requires-Dist: pytest>=8; extra == 'dev'
Provides-Extra: docs
Requires-Dist: mkdocs-material; extra == 'docs'
Description-Content-Type: text/markdown

# djmux

**One config, many DataJoint packages on one server.** `djmux` lets several DataJoint
table-set packages run side-by-side on the same MySQL server — each under its own schema
**prefix** — from a single shared config file. It patches nothing else about DataJoint.

## Why

DataJoint natively supports a *single* schema prefix. As soon as you have more than one table-set
package on a server — a shared lab pipeline, a couple of per-user downstream packages, a `v1` and a
`v2` of the same schema — they either collide or need each package to hardcode a prefix. `djmux`
solves this with **one YAML file** that provides:

- the shared MySQL connection (standard `dj.config` keys), and
- a **map of schema prefixes keyed by package**.

Each package's schemas are then named `<prefix>__<name>`, so many packages activate together with
**no package hardcoding a prefix**, and versioning (`v1 → v2`) is a one-line config edit. Everything
else works exactly like stock DataJoint — `djmux` only patches `dj.config`.

## Install

```sh
pip install djmux
```

## Use

A single config file (`~/.djmux.yaml`, or point `$DJMUX_CONFIG` at it):

```yaml
datajoint:                     # standard DataJoint connection
  host: db.lab
  port: 3306
  user: alice
  password: ...
  use_tls: true
prefixes:                      # one prefix per table-set package (v1 -> v2 = edit here)
  mypipeline: mypipeline_v1      #   shared pipeline package -> schemas mypipeline_v1__<name>
  mine:      alice_replay      #   your downstream package  -> schemas alice_replay__<name>
stores:                        # optional filepath@ external store(s)
  tree: { location: /data/store }
```

Then several packages activate together, each under its own prefix:

```python
import djmux, mypipeline, my_replay
djmux.load("~/.djmux.yaml")    # sets the shared connection + prefix map (once)
mypipeline.activate()         # -> mypipeline_v1__*
my_replay.activate()            # -> alice_replay__*
```

A package makes itself djmux-aware by decorating tables with a **deferred** schema and delegating
activation:

```python
import datajoint as dj, djmux
schema = dj.Schema()            # deferred (unnamed)

@schema
class Session(dj.Manual): ...

def activate(**kw):
    djmux.activate(schema, key="mypipeline", name="core", linking_module=__name__, **kw)
```

## API

| function | purpose |
|---|---|
| `djmux.load(path=None)` | read the YAML, patch `dj.config` (connection + `custom.prefixes` + `stores`); enables `filepath@` |
| `djmux.activate(schema, key, name, ...)` | activate a deferred `dj.Schema()` as `<prefix>__<name>` (prefix from config `key`) |
| `djmux.get_datajoint_schema(file, module, key)` | eager per-file modular schema, `<prefix>__<filestem>` (orm-patterns style) |
| `djmux.schema_name(key, name)` / `resolve_prefix(key)` | naming helpers |

Prefix resolution order: explicit `override=` arg → `$DJMUX_PREFIX_<KEY>` env → config `prefixes[key]`.
Credentials may live in `~/.datajoint_config.json` instead and be omitted from the djmux config.

## Development

```sh
git clone https://github.com/larsrollik/djmux.git
cd djmux
uv sync --extra dev
uv run pre-commit install --hook-type pre-commit --hook-type commit-msg
uv run pytest
```

## Release

Bump `VERSION`, merge to `main`; the tag triggers a GitHub release + **OIDC trusted-publish** to PyPI
(no tokens). See `.github/workflows/release.yml`.

## License

BSD-3-Clause — see [LICENSE](LICENSE).
