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
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

# API Configuration
API_VERSION=v2.0
ENVIRONMENT=development
ENVIRONMENT=dev

# Beacon Information
BEACON_ID=org.example.beacon
Expand Down
27 changes: 20 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ jobs:
run: |
uv pip install -e ".[dev]"

- name: Check formatting with black
- name: Check formatting with ruff
run: |
source .venv/bin/activate
black --check src/ tests/
ruff format --check src/ tests/

- name: Lint with ruff
run: |
Expand Down Expand Up @@ -85,25 +85,38 @@ jobs:
docker:
name: Build Docker Image
runs-on: ubuntu-latest
services:
registry:
image: registry:3
ports:
- 5000:5000

steps:
- uses: actions/checkout@v4

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
driver-opts: network=host

- name: Build Docker image
uses: docker/build-push-action@v5
with:
push: true
context: .
push: false
tags: beacon-api:latest
tags: localhost:5000/beacon-api:latest
cache-from: type=gha
cache-to: type=gha,mode=max

- name: Test Docker image
run: |
docker run -d -p 8000:8000 --name beacon-test beacon-api:latest
sleep 5
curl --fail http://localhost:8000/health || exit 1
docker run -d -p 8000:8000 --name beacon-test localhost:5000/beacon-api:latest
echo "Waiting for container to be ready..."
sleep 10
echo "Testing health endpoint..."
curl --fail --retry 3 --retry-delay 2 --retry-all-errors http://localhost:8000/api/monitor/health || {
echo "Health check failed. Container logs:"
docker logs beacon-test
exit 1
}
docker stop beacon-test
13 changes: 6 additions & 7 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
# Set working directory
WORKDIR /app

# Copy dependency files
COPY pyproject.toml ./
# Copy dependency files and source code
COPY pyproject.toml README.md ./
COPY src/ ./src/

# Create virtual environment and install dependencies
RUN uv venv /opt/venv && \
. /opt/venv/bin/activate && \
uv pip install --no-cache -e .
uv pip install --no-cache . && \
rm -rf /app/src /app/pyproject.toml /app/README.md

# Stage 2: Runtime
FROM python:3.12-slim
Expand All @@ -36,9 +38,6 @@ COPY --from=builder --chown=beacon:beacon /opt/venv /opt/venv
# Set working directory
WORKDIR /app

# Copy application code
COPY --chown=beacon:beacon src/ ./src/

# Switch to non-root user
USER beacon

Expand All @@ -47,7 +46,7 @@ EXPOSE 8000

# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"
CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/api/monitor/health')"

# Run the application
CMD ["uvicorn", "beacon_api.main:app", "--host", "0.0.0.0", "--port", "8000"]
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ A production-ready implementation of the [GA4GH Beacon v2 API](https://github.co
- ✅ **Production-ready** with Docker support and health checks
- ✅ **CI/CD** with GitHub Actions (linting, testing, Docker builds)
- ✅ **Configuration** using Pydantic Settings with environment variables
- ✅ **Modern tooling** - uv, ruff, black, mypy
- ✅ **Modern tooling** - uv, ruff, mypy

## Architecture

Expand Down Expand Up @@ -215,9 +215,9 @@ services:

### Code Quality

Format code with black:
Format code with ruff:
```bash
black src/ tests/
ruff format src/ tests/
```

Lint with ruff:
Expand Down
31 changes: 7 additions & 24 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ dev = [
"pytest-asyncio>=0.24.0",
"httpx>=0.27.0",
"ruff>=0.7.0",
"black>=24.10.0",
"mypy>=1.13.0",
]

Expand All @@ -44,7 +43,6 @@ dev = [
"pytest-asyncio>=0.24.0",
"httpx>=0.27.0",
"ruff>=0.7.0",
"black>=24.10.0",
"mypy>=1.13.0",
]

Expand All @@ -55,24 +53,6 @@ build-backend = "hatchling.build"
[tool.hatch.build.targets.wheel]
packages = ["src/beacon_api"]

[tool.black]
line-length = 88
target-version = ["py311", "py312"]
include = '\.pyi?$'
extend-exclude = '''
/(
# directories
\.eggs
| \.git
| \.hg
| \.mypy_cache
| \.tox
| \.venv
| build
| dist
)/
'''

[tool.ruff]
line-length = 88
target-version = "py311"
Expand Down Expand Up @@ -109,7 +89,7 @@ select = [
"UP", # pyupgrade
]
ignore = [
"E501", # line too long, handled by black
"E501", # line too long, handled by ruff formatter
"B008", # do not perform function calls in argument defaults
"C901", # too complex
]
Expand All @@ -120,12 +100,15 @@ ignore = [
[tool.ruff.lint.isort]
known-third-party = ["fastapi", "pydantic", "uvicorn"]

[tool.ruff.format]
quote-style = "double"
indent-style = "space"
skip-magic-trailing-comma = false
line-ending = "auto"

[tool.pytest.ini_options]
minversion = "8.0"
addopts = "-ra -q --strict-markers --cov=src/beacon_api --cov-report=term-missing --cov-report=html"
testpaths = ["tests"]
pythonpath = ["src"]
asyncio_mode = "auto"

[tool.mypy]
python_version = "3.11"
Expand Down
12 changes: 6 additions & 6 deletions src/beacon_api/api/__init__.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
"""FastAPI routers for Beacon v2 API endpoints."""

from beacon_api.api.info import router as info_router
from beacon_api.api.individuals import router as individuals_router
from beacon_api.api.biosamples import router as biosamples_router
from beacon_api.api.genomic_variations import router as g_variations_router
from beacon_api.api.analyses import router as analyses_router
from beacon_api.api.biosamples import router as biosamples_router
from beacon_api.api.cohorts import router as cohorts_router
from beacon_api.api.datasets import router as datasets_router
from beacon_api.api.runs import router as runs_router
from beacon_api.api.genomic_variations import router as g_variations_router
from beacon_api.api.individuals import router as individuals_router
from beacon_api.api.info import router as info_router
from beacon_api.api.monitor import router as monitor_router
from beacon_api.api.runs import router as runs_router

__all__ = [
"info_router",
Expand All @@ -19,5 +19,5 @@
"cohorts_router",
"datasets_router",
"runs_router",
"monitor_router"
"monitor_router",
]
Loading
Loading