Metadata-Version: 2.4
Name: opencloning-db
Version: 1.7.0
Summary: Database for OpenCloning, a web application to generate molecular cloning strategies in json format, and share them with others.
Project-URL: Repository, https://github.com/OpenCloning/OpenCloning_backend
Author-email: Manuel Lera-Ramirez <manulera14@gmail.com>
License-Expression: MIT
Requires-Python: <4,>=3.11
Requires-Dist: alembic>=1.18.4
Requires-Dist: boto3<2,>=1.43.10
Requires-Dist: botocore<2,>=1.43.10
Requires-Dist: fastapi-pagination<0.16,>=0.15.10
Requires-Dist: fastapi>=0.135.3
Requires-Dist: gunicorn>=26.0.0
Requires-Dist: opencloning-linkml>=1.0.0
Requires-Dist: opencloning==1.7.0
Requires-Dist: psycopg[binary]<4,>=3.2
Requires-Dist: pwdlib[argon2]<0.3,>=0.2.1
Requires-Dist: pydantic[email]>=2.7.1
Requires-Dist: pydna>=5.5.11
Requires-Dist: pyjwt<3,>=2.10.1
Requires-Dist: sqlalchemy<3,>=2.0.41
Requires-Dist: starlette>=1.0.0
Description-Content-Type: text/markdown

# opencloning-db

`opencloning-db` is the database/API companion package for the OpenCloning backend. It provides the app and local data workflows used for OpenCloning database features.

## Run locally

From the repository root:

```bash
# Install or update workspace dependencies
uv sync

# If you are using mac, you may have to stop any local Postgres instances running on port 5432
brew services stop postgresql

# Start local Postgres with dev/test/e2e databases plus Garage for object storage
docker compose \
    -f docker/docker-compose.postgres.yml \
    -f docker/docker-compose.garage.yml \
    up -d postgres garage

# Load required local runtime config
source .env.dev

# Apply schema migrations (creates tables on an empty database)
uv run opencloning-cli db migrate

# Optional: load the deterministic demo/test baseline
OPENCLONING_TESTING=1 uv run opencloning-cli db seed

# Run both the cloning and the database API - this what the OpenCloningDB frontend expects
uv run uvicorn opencloning_db.combined:app --reload --reload-exclude='.venv'

# Run the opencloning-db API (only database, not cloning. This is not used when running with the frontend)
uv run uvicorn opencloning_db.api:app --reload --reload-exclude='.venv'
```

That will serve the cloning API at [http://127.0.0.1:8000/cloning](http://127.0.0.1:8000/cloning) and the database API at [http://127.0.0.1:8001/db](http://127.0.0.1:8001/db). That's what the OpenCloningDB frontend expects.

When the cloning app is served through `opencloning_db.combined`, the entire `/cloning` mount is protected by the same bearer-token authentication used by the db API.

## Database migrations (Alembic)

Schema changes are defined in **`opencloning_db.models`** and applied with **Alembic** in this package (`alembic/`, `alembic.ini`). Edit the models first, add or adjust a revision under `alembic/versions/`, then run migrations against each database.

Alembic reads the database URL from **`OPENCLONING_DB_URL`** (same as the app; load `.env.dev` for local work). Revision history is stored in the database table `alembic_version`, not in git.

From the repository root, pass the config file explicitly (or `cd packages/opencloning-db` and omit `-c`):

```bash
ALEMBIC_CFG=packages/opencloning-db/alembic.ini
# Use -c "$ALEMBIC_CFG" (quoted). Do not put -c inside the variable: zsh does not
# split $ALEMBIC on spaces, so `ALEMBIC="-c …"; alembic $ALEMBIC` breaks.
```

### Autogenerate a migration

With Postgres running and `.env.dev` loaded:

```bash
source .env.dev
ALEMBIC_CFG=packages/opencloning-db/alembic.ini

# Optional: see which revision the database is at
uv run alembic -c "$ALEMBIC_CFG" current

# 1. Change src/opencloning_db/models.py first (desired end state).
# 2. Generate a revision by diffing models against the live database:
uv run alembic -c "$ALEMBIC_CFG" revision --autogenerate -m "short description of the change"

# 3. Open the new file under packages/opencloning-db/alembic/versions/ and review it.
#    Autogenerate can miss or mis-handle partial indexes, renames, and data backfills.
```

The database you point at must reflect the **previous** migration state (run `alembic upgrade head` first, or use a fresh DB). If the schema already matches your models but `alembic_version` is empty, stamp instead of upgrading (see below).

### Run migrations

```bash
source .env.dev
ALEMBIC_CFG=packages/opencloning-db/alembic.ini

# Apply all pending revisions (CLI wrapper or Alembic directly)
uv run opencloning-cli db migrate
# uv run alembic -c "$ALEMBIC_CFG" upgrade head

# Confirm
uv run alembic -c "$ALEMBIC_CFG" current
```

To migrate a different database (for example the test DB), set `OPENCLONING_DB_URL` to that database before running Alembic.

**Schema already up to date?** If the live database already has the objects a migration would add (for example after a manual change or an older deploy), `upgrade` may fail with “already exists”. Mark the database as migrated without running SQL:

```bash
uv run alembic -c "$ALEMBIC_CFG" stamp head
```

Use `stamp` only when you are sure the live schema matches the migration chain at `head`.

### Useful commands

| Command | Purpose |
| --- | --- |
| `uv run alembic -c "$ALEMBIC_CFG" history` | List revisions |
| `uv run alembic -c "$ALEMBIC_CFG" downgrade -1` | Revert the last revision |
| `uv run alembic -c "$ALEMBIC_CFG" upgrade head --sql` | Print SQL without executing (offline preview) |

## Running tests locally

From the repository root:

```bash
# Install or update workspace dependencies
uv sync

# Run the tests
uv run pytest packages/opencloning-db/tests -v -ks
```

## Frontend testing

Frontend testing using the database requires reseeding after tests that modify the database. You can do this by calling the `/__test/reset-db` endpoint with the `X-Test-Reset-Token` header set to `RESET-TOKEN`. That endpoint is only available if the `OPENCLONING_TESTING` environment variable is set to `1`, and it delegates to the guarded `opencloning-cli db seed` command.

## Building and running the Docker image

The Dockerfile is shared with the cloning app, and the build arg `APP_TARGET` determines which app to build. So you can build the image by running:

```bash
docker build -f docker/opencloning.Dockerfile --build-arg APP_TARGET=db -t manulera/opencloning-db-backend .
```

Then run it for development:

```bash
# Run the containers (Postgres + Garage + db API)
docker compose \
    -f docker/docker-compose.postgres.yml \
    -f docker/docker-compose.garage.yml \
    -f docker/docker-compose.opencloning-db.yml \
    up -d
```

That stack exposes Garage's S3-compatible API at [http://127.0.0.1:9000](http://127.0.0.1:9000). Garage does not provide a MinIO-style browser console in this setup, so use an S3 client such as `awscli` or `mc` if you need to inspect the local bucket. The local defaults in `.env.dev` point host-side `uv run ...` commands at the same Garage bucket used by the containerized db API.
