Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
229e1ca
Create basic Dockerfile
ramonechen Apr 21, 2026
d5b8582
Add DB root password to .env and move to project root
ramonechen Apr 21, 2026
dec915d
Add Docker and Docker Compose files
ramonechen Apr 21, 2026
0e540fd
Remove redundant variable names in Docker Compose
ramonechen Apr 22, 2026
8e8d827
Restore .env variable interpolation
ramonechen Apr 22, 2026
9531ebe
Fix DB health check passing prematurely
ramonechen Apr 22, 2026
b658cfe
Second fix to DB health check
ramonechen Apr 22, 2026
201957a
Remove hardcoded variable values in Docker Compose
ramonechen Apr 22, 2026
c47f74e
Modify Black check to call shared workflow
ramonechen Apr 23, 2026
3831cba
Enhance Dockerfile readability
ramonechen Apr 23, 2026
5d59083
Create .dockerignore
ramonechen Apr 23, 2026
fc5b97c
Include shared dev Compose and refactor API service
ramonechen Apr 23, 2026
1144b0e
Add clarifying comment to Dockerfile
ramonechen Apr 23, 2026
bb55705
Create image-publish.yml
ramonechen Apr 23, 2026
f532cd8
Make environment variables explicit
ramonechen Apr 23, 2026
702ee35
Add comment in Compose to clarify possible warning
ramonechen Apr 28, 2026
5a83d14
Remove mention of shared Docker network in Compose
ramonechen Apr 28, 2026
2557b9b
Clarify example.env
ramonechen Apr 28, 2026
7ab0892
Fill in README
ramonechen Apr 28, 2026
a2a62bf
Add --service-ports to Compose command
ramonechen Apr 28, 2026
1137df4
Update README setup command
ramonechen Apr 28, 2026
420a5ba
Add helpful runtime tips to README
ramonechen Apr 28, 2026
f540bf0
Remove DB_ROOT_PASSWORD from Compose
ramonechen Apr 29, 2026
ee772e7
Reduce layering in Dockerfile
ramonechen Apr 29, 2026
f7f6ec6
Add dev and prod stages to Dockerfile
ramonechen Apr 29, 2026
3ed1060
Remove Compose watch directive
ramonechen Apr 29, 2026
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
15 changes: 15 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Ignore all files

*

# Whitelist necessary build files
!requirements.txt

# Allow Docker to read app directory
!app/

# Ignore everything inside app
app/*

# Only allow .py files within app and its subdirectories
!app/**/*.py
28 changes: 7 additions & 21 deletions .github/workflows/black-check.yml
Original file line number Diff line number Diff line change
@@ -1,25 +1,11 @@
name: Black Check
name: Black Formatting Check

# Run on every push and pull request
on: [push, pull_request]

jobs:
format-check:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v2

- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.12.2'

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install black

- name: Run Black check
run: black --check .

call-format-check:
uses: project-carpi/.github/.github/workflows/black-check.yml@main
Comment thread
ramonechen marked this conversation as resolved.
permissions:
contents: read
secrets: inherit
15 changes: 15 additions & 0 deletions .github/workflows/image-publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name: Build and Push Docker Image to GHCR

# Run this workflow every time code is pushed or merged to the main branch
on:
push:
branches:
- main

jobs:
call-build-and-push:
uses: project-carpi/.github/.github/workflows/image-publish.yml@main
Comment thread
ramonechen marked this conversation as resolved.
permissions:
contents: read
packages: write
secrets: inherit
31 changes: 31 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
FROM python:3.12-slim AS base

# Git is needed to install the git-based dependency in requirements.txt
RUN apt-get update && \
apt-get install -y git && \
rm -rf /var/lib/apt/lists/*

# Store all application files in /api
WORKDIR /api

# Copy the requirements file and install dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Copy the rest of the application code into the container
COPY . .

# Indicate that the container should listen on port 8000
EXPOSE 8000

# --- DEVELOPMENT STAGE ---
FROM base as dev

# Run Uvicorn with reload enabled for development
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]

### --- PRODUCTION STAGE ---
FROM base as prod

# Run Uvicorn for production
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
38 changes: 36 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,37 @@
# CARPI-Backend-FastAPI
# CARPI Course Planner - API

FastAPI re-write of the old Spring Boot API.
This is the API service for the CARPI Course Planner application. It is designed to work in tandem with the [frontend](https://github.com/Project-CARPI/site) and [SIS scraper](https://github.com/Project-CARPI/sis-scraper).

## Running the API

### Prerequisites

- **[Docker](https://www.docker.com/products/docker-desktop/)** (Required): Used for the streamlined development environment setup.
- **[Python >= 3.12](https://www.python.org/)** (Optional): Useful for code editor linting or running the API locally without Docker.

### Setup Instructions

**1. Configure Environment Variables**

Create a copy of the `example.env` file in the project root and rename it to `.env`.

The default values provided in the example file will work out of the box, but they can be customized as needed.

**2. Start the Development Environment**

With Docker Engine running, execute the following command in your terminal:

```bash
docker compose run --rm --service-ports api && docker compose down
```

While the container is running:

- **Live Reloading:** Local files are mounted to the running container, so the API service will automatically respond to live changes in your source code.
Comment thread
ramonechen marked this conversation as resolved.
- **API Documentation:** A list of endpoint definitions and interactive Swagger documentation can be found at http://localhost:8000/docs.

### About the Database Environment

- **Shared Database:** The development environment pulls a shared MySQL database service definition from an external repository, creating a local database volume.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we discussed, you should update this section to include the caveat of only one of the scraper and API being able to use the database container at once.

- **Data Persistence:** The test database volume persists between Docker start and stop cycles, ensuring test data remains available across development sessions and for other services that depend on the database.
- **Resetting the Database:** To completely rebuild the database from scratch, you must manually remove the corresponding Docker volume prior to starting the environment.
7 changes: 4 additions & 3 deletions app/dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
from contextlib import asynccontextmanager
from typing import Annotated, AsyncGenerator, Generator

import carpi_data_model.models as models
from fastapi import Depends, FastAPI
from pydantic_settings import BaseSettings, SettingsConfigDict
from sqlalchemy.engine import Engine
from sqlalchemy import create_engine
from sqlalchemy.engine import Engine
from sqlalchemy.orm import Session, sessionmaker
import carpi_data_model.models as models


class _Settings(BaseSettings):
Expand All @@ -18,7 +18,8 @@ class _Settings(BaseSettings):
db_password: str
db_schema: str
model_config = SettingsConfigDict(
env_file=os.path.join(os.path.dirname(__file__), ".env")
env_file=os.path.join(os.path.dirname(os.path.dirname(__file__)), ".env"),
extra="ignore",
)


Expand Down
8 changes: 0 additions & 8 deletions app/example.env

This file was deleted.

52 changes: 52 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Docker Compose configuration for the CARPI API environment.
#
# This Compose file includes a shared development environment configuration
# from the Project-CARPI/.github repository, which contains a database service.
#
# To start the development environment, run:
# docker compose run --rm --service-ports api && docker compose down
#
# This will start both the shared development environment and the carpi-api
# container. After the API container is stopped, the "docker compose down" will
# stop the shared development environment.
#
# A warning may appear about the test database volume already existing. This is
# expected and can be safely ignored.
#
# The test database volume persists between Docker start and stop cycles so
# that test data remains available across both development sessions and other
# services that depend on the database. The volume must be manually removed in
# order to build the database from scratch.

name: carpi-api-dev-environment

include:
- https://github.com/Project-CARPI/.github.git#main:shared-dev-env/docker-compose.yml
Comment thread
ramonechen marked this conversation as resolved.

services:
api:
build:
context: .
target: dev
image: carpi-api:latest
container_name: carpi-api
# Ensure image is built locally and is not pulled from a registry
pull_policy: build
restart: on-failure
ports:
- "8000:8000"
environment:
DB_DIALECT: ${DB_DIALECT}
DB_API: ${DB_API}
# Hardcode the DB_HOSTNAME environment variable
DB_HOSTNAME: db:3306
DB_USERNAME: ${DB_USERNAME}
DB_PASSWORD: ${DB_PASSWORD}
DB_SCHEMA: ${DB_SCHEMA}
# Mount local code over the code built into the container for automatic
# reloading during development.
volumes:
- .:/api
depends_on:
db:
condition: service_healthy
16 changes: 16 additions & 0 deletions example.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Create a file named ".env" in this directory with the following variables.
# If using Docker Compose for development, these values can be used as-is.

# This only needs to be set if the database is different from the one used
# in the Docker Compose environment.
DB_HOSTNAME="hostname:port"

# This root password is only used for instantiating the MySQL container in
# Docker Compose.
DB_ROOT_PASSWORD="password"

DB_DIALECT="mysql"
DB_API="mysqlconnector"
DB_USERNAME="username"
DB_PASSWORD="password"
DB_SCHEMA="schema"