Skip to content

Commit a94a850

Browse files
Merge pull request #16 from DJSaunders1997/feature/use_uv
Feature/use uv
2 parents b60328d + e6b76e1 commit a94a850

21 files changed

Lines changed: 2586 additions & 238 deletions

.github/copilot-instructions.md

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,12 @@ DEEPSEEK_API_KEY=...
6464
# Full stack with Docker Compose
6565
docker-compose up --build
6666

67-
# Backend only (for API development)
68-
cd backend && uvicorn fastapi_generate_quiz:app --reload --host 0.0.0.0 --port 8000
67+
# Backend only (for API development) - UV method
68+
cd backend && uv sync --dev --no-install-project && uv run --script dev
69+
70+
# Testing
71+
uv run pytest -v # Unit tests only (no API calls)
72+
uv run pytest -m integration # Integration tests with real API calls
6973

7074
# Access points:
7175
# - Frontend: http://localhost:8080
@@ -79,10 +83,11 @@ cd backend && uvicorn fastapi_generate_quiz:app --reload --host 0.0.0.0 --port 8
7983

8084
## Code Quality Standards
8185

82-
- **Linting**: Uses `ruff` for Python code formatting and linting
86+
- **Package Management**: Uses UV for fast dependency management and virtual environments
87+
- **Linting**: Uses `ruff` for Python code formatting and linting (`uv run ruff check .`)
8388
- **Type Checking**: Expected for new Python code
8489
- **Testing**: Always add unit tests; integration tests for API changes
85-
- **Dependencies**: Keep `requirements.txt` minimal; dev dependencies in `requirements-dev.txt`
90+
- **Dependencies**: Managed via `pyproject.toml`; dev dependencies in `[project.optional-dependencies]`
8691

8792
## Common Development Tasks
8893

.github/workflows/ci_python.yml

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,23 @@ jobs:
2121
with:
2222
python-version: "3.10"
2323

24+
- name: Install UV
25+
run: curl -LsSf https://astral.sh/uv/install.sh | sh
26+
2427
- name: Install dependencies
2528
run: |
26-
# Install ruff for linting and the development requirements (including pytest)
27-
pip install -r backend/requirements-dev.txt
29+
source $HOME/.cargo/env
30+
cd backend
31+
uv sync --dev --no-install-project
2832
2933
- name: Lint Python with ruff 🚀
30-
run: ruff check backend/
34+
run: |
35+
source $HOME/.cargo/env
36+
cd backend
37+
uv run ruff check .
3138
3239
- name: Run Pytest 🧪
33-
run: pytest -q backend/tests/ -v
40+
run: |
41+
source $HOME/.cargo/env
42+
cd backend
43+
uv run pytest -q tests/ -v -m "not integration"

.vscode/settings.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@
77
"azureFunctions.projectRuntime": "~4",
88
"debug.internalConsoleOptions": "neverOpen",
99
"python.testing.pytestArgs": [
10-
"backend"
10+
"backend",
11+
"-v"
1112
],
1213
"python.testing.unittestEnabled": false,
13-
"python.testing.pytestEnabled": true
14+
"python.testing.pytestEnabled": true,
15+
"python-envs.pythonProjects": []
1416
}

README.md

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,25 +54,37 @@ This project uses Docker Compose to run both the FastAPI backend and the fronten
5454
### Running Locally
5555

5656
1. **Set Environment Variables**
57-
Make sure your `OPENAI_API_KEY` is set in your environment or in a `.env` file at the project root:
57+
Make sure your API keys are set in your environment or in a `.env` file at the project root:
5858
```sh
5959
export OPENAI_API_KEY=your_openai_api_key_here
60+
export GEMINI_API_KEY=your_gemini_api_key_here
61+
# ... other API keys
6062
```
6163
Or create a `.env` file with:
6264
```
6365
OPENAI_API_KEY=your_openai_api_key_here
66+
GEMINI_API_KEY=your_gemini_api_key_here
67+
# ... other API keys
6468
```
6569

66-
2. **Build and Run the Containers**
70+
2. **Build and Run with Docker Compose**
6771
From the project root, run:
6872
```sh
6973
docker-compose up --build
7074
```
7175
This command builds and starts both the backend and frontend containers.
7276

77+
3. **Alternative: Run Backend Locally with UV**
78+
For faster development iteration:
79+
```sh
80+
cd backend
81+
uv sync --dev
82+
uv run uvicorn fastapi_generate_quiz:app --reload --host 0.0.0.0 --port 8000
83+
```
84+
7385
3. **Access the Services**
7486
- **Backend API (FastAPI)**: [http://localhost:8000](http://localhost:8000)
7587
- **Frontend**: [http://localhost:8080](http://localhost:8080)
7688

77-
With these steps, you can easily test both the backend API and the static frontend locally using Docker Compose.
89+
With these steps, you can easily test both the backend API and the static frontend locally using Docker Compose or UV for faster backend development.
7890

backend/Dockerfile

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,23 @@
22
# https://fastapi.tiangolo.com/deployment/docker/#dockerfile
33
FROM python:3.10-slim
44

5+
# Install UV
6+
COPY --from=ghcr.io/astral-sh/uv:latest /uv /bin/uv
7+
58
# Set working directory
69
WORKDIR /code
710

8-
# Copy requirements file and install dependencies
9-
COPY ./requirements.txt /code/requirements.txt
10-
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
11+
# Copy project files
12+
COPY ./pyproject.toml /code/pyproject.toml
13+
14+
# Install dependencies without installing the project itself
15+
RUN uv sync --no-dev --no-install-project
1116

1217
# Copy application code
1318
COPY . /code
1419

1520
# Command to run the application using Uvicorn
16-
CMD ["uvicorn", "fastapi_generate_quiz:app", "--host", "0.0.0.0", "--port", "8000"]
21+
CMD ["uv", "run", "uvicorn", "fastapi_generate_quiz:app", "--host", "0.0.0.0", "--port", "8000"]
1722

1823
# docker build -t fastapi_generate_quiz:latest . # Build container
1924
# docker run -p 8000:8000 -e OPENAI_API_KEY fastapi_generate_quiz:latest # Run container

backend/README.md

Lines changed: 64 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,59 @@ Certain functions may require environment variables (e.g., `OPENAI_API_KEY`). Th
3434
## Debug
3535
To debug locally, follow these steps:
3636

37+
### Using UV (Recommended)
38+
39+
1. **Install UV** (if not already installed):
40+
```sh
41+
curl -LsSf https://astral.sh/uv/install.sh | sh
42+
```
43+
44+
2. **Install dependencies**:
45+
```sh
46+
cd backend
47+
uv sync --dev --no-install-project
48+
```
49+
50+
3. **Run the FastAPI application**:
51+
```sh
52+
# Option 1: Using the configured script
53+
uv run --script dev
54+
55+
# Option 2: Direct command
56+
uv run uvicorn fastapi_generate_quiz:app --reload --host 0.0.0.0 --port 8000
57+
```
58+
59+
4. **Test the endpoints** (requires valid API keys and quota):
60+
```sh
61+
# Test quiz generation (will fail if no API quota)
62+
curl "http://localhost:8000/GenerateQuiz?topic=UK%20History&difficulty=easy&n_questions=3"
63+
64+
# Test image generation
65+
curl "http://localhost:8000/GenerateImage?prompt=A%20Juicy%20Burger"
66+
```
67+
68+
5. **Run tests**:
69+
```sh
70+
# Unit tests only (default - no API calls required)
71+
uv run pytest -v
72+
73+
# Integration tests (requires API keys and quota)
74+
uv run pytest -m integration
75+
76+
# All tests
77+
uv run pytest -v --tb=short
78+
```
79+
80+
6. **Run linting**:
81+
```sh
82+
uv run ruff check .
83+
uv run ruff format .
84+
```
85+
86+
> **Note**: Direct execution of `generate_quiz.py` requires valid API keys and quota. For development without making API calls, use the unit tests (`uv run pytest -v`) which use mocked responses.
87+
88+
### Using Docker
89+
3790
1. **Build the Docker container**:
3891
```sh
3992
docker build -t fastapi_generate_quiz:latest .
@@ -56,6 +109,8 @@ To debug locally, follow these steps:
56109
curl "http://localhost:8000/GenerateImage?prompt=Kangeroo%20Playing%20BasketBall"
57110
```
58111

112+
### Docker Registry Commands
113+
59114
4. **Tag the Docker image for GitHub Container Registry**:
60115
```sh
61116
docker tag fastapi_generate_quiz:latest ghcr.io/djsaunders1997/fastapi_generate_quiz:latest
@@ -78,27 +133,28 @@ Our test suite is divided into **unit tests** and **integration tests**.
78133

79134
### Default Behavior
80135

81-
By default, integration tests are **excluded** from the test run. This is achieved by configuring `pytest` in our `pytest.ini` file (located in the `backend` directory):
136+
By default, integration tests are **excluded** from the test run. This is achieved by configuring `pytest` in our `pyproject.toml` file:
82137

83-
```ini
84-
[pytest]
85-
markers =
86-
integration: mark test as an integration test.
87-
addopts = -m "not integration"
138+
```toml
139+
[tool.pytest.ini_options]
140+
markers = [
141+
"integration: mark test as an integration test."
142+
]
143+
addopts = "-m 'not integration'"
88144
```
89145

90146
This configuration tells `pytest` to skip any test marked with `@pytest.mark.integration` when you run:
91147

92148
```bash
93-
pytest -v
149+
uv run pytest -v
94150
```
95151

96152
### Running Integration Tests
97153

98154
To run the integration tests, override the default marker filter by using the `-m` option:
99155

100156
```bash
101-
pytest -m integration
157+
uv run pytest -m integration
102158
```
103159

104160
> **Note:** Integration tests make real API calls and require the `OPENAI_API_KEY` environment variable to be set. Make sure you have this environment variable configured before running these tests.

0 commit comments

Comments
 (0)