Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<!--
Thank you for contributing! Please fill out the sections below to help maintainers review your change faster.
Delete any sections that don't apply.
-->

# Pull Request

## Summary
[SBP-XXX](https://biocloud.atlassian.net/browse/SBP-XXX) <Provide a short description of the changes in this pull request and the motivation behind them.>

## Changes
- <What changed? (files, components, behavior)>
- <Any migration or backwards-incompatible changes?>

## How to Test
<Provide step-by-step instructions for testing the changes locally. Include any setup, commands, or screenshots where helpful.>

## Type of change
- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)
- [ ] Documentation update

## Checklist
- [ ] I have added tests that prove my fix is effective or that my feature works
- [ ] I have added or updated documentation where necessary
- [ ] I have run linting and unit tests locally
- [ ] The code follows the project's style guidelines
37 changes: 37 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: Lint

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
ruff:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"

- name: Install UV
uses: astral-sh/setup-uv@v5
with:
enable-cache: true

- name: Install dependencies
run: |
uv sync --all-extras

- name: Run Ruff
run: uv run ruff check app tests

- name: Run Black
run: uv run black --check app tests

- name: Run MyPy
run: uv run mypy app --ignore-missing-imports
60 changes: 60 additions & 0 deletions .github/workflows/test-coverage.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: Coverage

on:
push:
branches: ["main"]
pull_request:
branches: ["main"]

jobs:
tests:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.10", "3.11", "3.12"]

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- name: Install UV
uses: astral-sh/setup-uv@v5
with:
enable-cache: true

- name: Install dependencies
run: |
uv sync --all-extras

- name: Run tests with coverage
env:
ALLOWED_ORIGINS: http://localhost
SEQERA_API_URL: https://example.com/api
SEQERA_ACCESS_TOKEN: test-token
WORK_SPACE: demo-workspace
COMPUTE_ID: compute-123
WORK_DIR: /tmp/work
run: |
uv run pytest --cov=app --cov-report=xml --cov-report=term-missing --cov-report=html -v

- name: Check coverage threshold (90%)
run: |
uv run coverage report --fail-under=90

- name: Coverage summary
uses: irongut/CodeCoverageSummary@v1.3.0
with:
filename: coverage.xml
badge: true
fail_below_min: true
format: markdown
hide_branch_rate: false
hide_complexity: true
indicators: true
thresholds: "90 90"
output: both
35 changes: 34 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,41 @@
# Python
.venv/
venv/
env/
__pycache__/
*.py[cod]
*$py.class
*.so
*.egg
*.egg-info/
dist/
build/
*.whl

# Environment
.env
*.log
.env.local
.env.*.local

# Testing
.pytest_cache/
.coverage
htmlcov/
.tox/
.hypothesis/

# IDE
.DS_Store
.idea/
.vscode/
*.swp
*.swo
*~

# Logs
*.log
logs/

# UV
# Note: uv.lock is tracked for reproducibility
# .python-version is tracked if using specific Python version
32 changes: 32 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Pre-commit hooks configuration
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-added-large-files
- id: check-json
- id: check-toml
- id: check-merge-conflict
- id: debug-statements

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.14.10
hooks:
- id: ruff
args: [--fix, --exit-non-zero-on-fix]

- repo: https://github.com/psf/black
rev: 24.1.1
hooks:
- id: black
language_version: python3.11

- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.8.0
hooks:
- id: mypy
additional_dependencies: [types-httpx]
args: [--ignore-missing-imports]
16 changes: 10 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,21 @@
FROM python:3.11-slim AS base

ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
PIP_NO_CACHE_DIR=1
PYTHONUNBUFFERED=1

WORKDIR /app

COPY requirements.txt ./
RUN pip install --upgrade pip && \
pip install --no-cache-dir -r requirements.txt
# Install UV
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv

# Copy dependency files
COPY pyproject.toml uv.lock ./

# Install dependencies
RUN uv sync --frozen --no-dev

COPY app ./app

EXPOSE 3000

CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "3000"]
CMD ["uv", "run", "uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "3000"]
67 changes: 59 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,32 @@
# SBP Portal Backend Server

![Lint](https://github.com/AustralianBioCommons/sbp-backend/actions/workflows/lint.yml/badge.svg)
![Coverage](https://github.com/AustralianBioCommons/sbp-backend/actions/workflows/test-coverage.yml/badge.svg)
[![codecov](https://codecov.io/gh/AustralianBioCommons/sbp-backend/branch/main/graph/badge.svg)](https://codecov.io/gh/AustralianBioCommons/sbp-backend)

FastAPI backend for handling Seqera Platform workflow launches.

## Prerequisites

- Python 3.9+ (matching the version used by your deployment target)
- [uvicorn](https://www.uvicorn.org/) and other dependencies listed in `requirements.txt`
- Python 3.10+
- [UV](https://docs.astral.sh/uv/) package manager

## Setup

1. Create a virtual environment (recommended):
1. Install UV (if not already installed):

```bash
python3 -m venv .venv
source .venv/bin/activate
# macOS/Linux
curl -LsSf https://astral.sh/uv/install.sh | sh

# Windows
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
```

2. Install dependencies:

```bash
pip install -r requirements.txt
uv sync --all-extras
```

3. Configure environment variables:
Expand All @@ -32,8 +39,7 @@ FastAPI backend for handling Seqera Platform workflow launches.
4. Run the API locally:

```bash
uvicorn app.main:app --reload --host 0.0.0.0 --port 3000
# or: python -m app.main (uses PORT/UVICORN_RELOAD variables)
uv run uvicorn app.main:app --reload --host 0.0.0.0 --port 3000
```

## API Endpoints
Expand All @@ -46,6 +52,51 @@ FastAPI backend for handling Seqera Platform workflow launches.
- `GET /api/workflows/{runId}/details` — Placeholder details endpoint
- `POST /api/workflows/datasets/upload` — Create a Seqera dataset and upload submitted form data as a CSV

## Testing

Run the test suite with coverage:

```bash
# Run all tests with coverage report
uv run pytest --cov=app --cov-report=term-missing --cov-report=html

# Run tests with verbose output
uv run pytest -v

# Run specific test file
uv run pytest tests/test_main.py

# Check coverage threshold (90%)
uv run coverage report --fail-under=90
```

View HTML coverage report:

```bash
open htmlcov/index.html # macOS
xdg-open htmlcov/index.html # Linux
start htmlcov/index.html # Windows (Command Prompt / PowerShell)
```

## Linting and Code Quality

```bash
# Run ruff linter
uv run ruff check app tests

# Run black formatter
uv run black app tests

# Run type checking with mypy
uv run mypy app --ignore-missing-imports

# Install pre-commit hooks
uv run pre-commit install

# Run pre-commit on all files
pre-commit run --all-files
```

## Environment Variables

Required entries in `.env`:
Expand Down
5 changes: 4 additions & 1 deletion app/main.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""FastAPI application entry point for the SBP Portal backend."""

from __future__ import annotations

import logging
Expand Down Expand Up @@ -29,7 +30,9 @@ def create_app() -> FastAPI:
if not allowed_origins_env:
raise RuntimeError("ALLOWED_ORIGINS environment variable is required but not set")

allowed_origins = [origin.strip() for origin in allowed_origins_env.split(",") if origin.strip()]
allowed_origins = [
origin.strip() for origin in allowed_origins_env.split(",") if origin.strip()
]

app.add_middleware(
CORSMiddleware,
Expand Down
Loading