# Applied Protein Biology (APB) Toolkit

This repo contains a Python package called `apb`.

[DESCRIPTION OF WHAT THE PACKAGE DOES].

## Installation

The package is hosted on PyPI and can be installed using pip:

```bash
pip install arcadia-apb
```

To use the `biomodal` subpackage for GPU-accelerated compute on Modal (ESM2 embeddings, perplexity, etc.), install with the `modal` extra. This requires access to the Arcadia-Science Modal workspace.

```bash
pip install arcadia-apb[modal]
```


## Usage

[DOCUMENTATION ABOUT HOW TO USE THE PACKAGE]

## Development

### Environment setup

We use [uv](https://docs.astral.sh/uv/) for dependency management and build tooling. Some tests depend on third-party binaries (TMalign, Foldseek) that are installed via conda. First, create a conda environment and install these binaries:

```bash
conda env create -n apb-dev -f envs/dev.yml
conda activate apb-dev
```

Next, install all dependencies:

```bash
uv sync --group dev --group docs --extra modal
```

The uv virtualenv lives outside the conda env, but the conda env must be activated so the third-party binaries are on PATH.

### Formatting and linting

To format the code, use the following command:

```bash
make format
```

To run the lint checks and type checking, use the following command:

```bash
make lint
```

### Pre-commit hooks

We use pre-commit to run formatting and lint checks before each commit. To install the pre-commit hooks, use the following command:

```bash
pre-commit install
```

To run the pre-commit checks manually, use the following command:

```bash
make pre-commit
```

### Testing

We use `pytest` for testing. Tests are module specific and exist alongside their corresponding module, prefixed with `test_`. To run the tests, use the following command:

```bash
make test
```

### Managing dependencies

We use uv to manage dependencies. To add a new dependency, use the following command:

```bash
uv add some-package
```

To add a new development dependency, use the following command:

```bash
uv add --group dev some-dev-package
```

To update a dependency, use the following command:

```bash
uv lock --upgrade-package some-package
```

Whenever you add or update a dependency, uv will automatically update both `pyproject.toml` and the `uv.lock` file. Make sure to commit the changes to these files to the repo.

### Documentation

We use Sphinx for documentation with the [`furo` theme](https://github.com/pradyunsg/furo). We also use some Sphinx extensions (described below) to make the process of writing documentation easier.

To build the docs, first install `pandoc`. On macOS, this can be done using `brew`:

```
brew install pandoc
```

Then, build the docs using the following command:

```bash
make docs
```

Note: the `pandoc` dependency is only required by the `nbsphinx` extension. If this extension is removed, there is no need to install `pandoc`.

#### sphinx-autoapi

This extension generates API docs automatically from the docstrings in the source code. To do so, it requires that docstrings adhere to the Google or Numpy style. This style is described in the [Google Python Style Guide](https://google.github.io/styleguide/pyguide.html).

#### napolean

Rather than writing our docstrings in RST, we use this extension to convert Google and NumPy-style docstrings to RST at build time.

#### myst-parser

RST is complicated to write. This extension lets us write our docs in Markdown and then converts them to RST at build time.

#### nbsphinx

It is often convenient to write examples as Jupyter notebooks. This extension executes Jupyter notebooks and renders the results in the docs at build time. It requires `pandoc`, which can be installed using `brew install pandoc`.

#### Removing unused Sphinx extensions

To remove an unused extension, delete the corresponding line from the `extensions` list in `docs/conf.py` and delete the extension from the `docs` dependency group in `pyproject.toml`.

## Publishing the package on PyPI

Publishing the package on PyPI requires that you have API tokens for the test and production PyPI servers. You can find these tokens in your PyPI account settings. Create a `.env` file by coping `.env.copy` and add your tokens to this file.

We use semantic versioning of the form `MAJOR.MINOR.PATCH`. See [semver.org](https://semver.org/) for more information.

__Before starting, make sure that your local git repository is on `main`, is up-to-date, and does not contain uncommitted changes!__

First, set your release version:

```bash
RELEASE_VERSION=0.1.0
```

Update the version string in both of these files:
- `pyproject.toml` — the `version` field under `[project]`
- `src/apb/__init__.py` — the `__version__` variable

Commit the version bump:

```bash
git add pyproject.toml src/apb/__init__.py
git commit -m "Bump version to ${RELEASE_VERSION}"
```

Tag the commit and push:

```bash
git tag -a v${RELEASE_VERSION} -m "Release version ${RELEASE_VERSION}"
git push origin main v${RELEASE_VERSION}
```

If you need to delete a tag you've created, use the following command:

```bash
git tag -d v${RELEASE_VERSION}
```

If you already pushed the deleted tag to GitHub, you will also need to delete the tag from the remote repository:

```bash
git push origin :refs/tags/v${RELEASE_VERSION}
```

Once you've created the correct tag, build the package:

```bash
make build
```

The build artifacts are written to the `dist/` directory. Verify that the version in the filenames (e.g. `arcadia_apb-0.1.0.tar.gz`) matches your release version.

Next, check that you can publish the package to the PyPI test server:

```bash
make build-and-test-publish
```

The `build-and-test-publish` command calls `uv build` to build the package and then `uv publish` to upload the build artifacts to the test server.

Check that you can install the new version of the package from the test server:

```bash
pip install --index-url https://test.pypi.org/simple/ arcadia-apb==${RELEASE_VERSION}
```

If everything looks good, build and publish the package to the prod PyPI server:

```bash
make build-and-publish
```

Finally, check that you can install the new version of the package from the prod PyPI server:

```bash
pip install arcadia-apb==${RELEASE_VERSION}
```
