Skip to content
Open
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
67 changes: 48 additions & 19 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,65 @@ name: Backend CI
on:
push:
branches:
- main # Runs on every push to the main branch
- main
pull_request:
branches:
- main # Runs on PR to the main branch
- main

jobs:
test:
lint:
name: Lint and Format Check
runs-on: ubuntu-latest

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

- name: Install uv
uses: astral-sh/setup-uv@v2
with:
version: "latest"

- name: Set up Python
uses: actions/setup-python@v2
uses: actions/setup-python@v5
with:
python-version: '3.12'
cache: 'uv'

- name: Install Poetry
run: |
curl -sSL https://install.python-poetry.org | python3 -
export PATH="$HOME/.poetry/bin:$PATH" # Ensure Poetry is in the PATH
- name: Sync dependencies
working-directory: ./backend
run: uv sync --frozen --no-install-project --group dev

- name: Change to Backend Directory
run: cd backend # Change to the backend folder
- name: Lint with Ruff
working-directory: ./backend
run: uv run --no-sync ruff check app/

- name: Install dependencies with Poetry
run: |
cd backend # Change to the backend folder again if needed
poetry install --no-root # Install the dependencies using Poetry
- name: Format check with Ruff
working-directory: ./backend
run: uv run --no-sync ruff format app/ --check

test:
name: Test Suite
runs-on: ubuntu-latest

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

- name: Install uv
uses: astral-sh/setup-uv@v2
with:
version: "latest"

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
cache: 'uv'

- name: Sync dependencies
working-directory: ./backend
run: uv sync --frozen --no-install-project --group dev

- name: Create .env file with GitHub Secrets
run: |
Expand All @@ -56,7 +85,7 @@ jobs:
echo "LANGFUSE_SECRET_KEY=${{ secrets.LANGFUSE_SECRET_KEY }}" >> backend/app/.env
echo "LANGFUSE_PUBLIC_KEY=${{ secrets.LANGFUSE_PUBLIC_KEY }}" >> backend/app/.env
echo "LANGFUSE_HOST=${{ secrets.LANGFUSE_HOST }}" >> backend/app/.env
- name: Run Tests with Poetry
run: |
cd backend/app
poetry run pytest tests/ --maxfail=1 --disable-warnings -q

- name: Run Tests
working-directory: ./backend
run: uv run --no-sync pytest app/tests/ --maxfail=1 --disable-warnings -v
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ An AI-powered platform for discovering, analyzing, and exploring biomodels from
## Architecture
This is a monolithic repository containing both frontend and backend services:
- **Frontend**: Next.js 15 with TypeScript, Tailwind CSS, and Radix UI components
- **Backend**: FastAPI with Python 3.12+, Poetry for dependency management
- **Backend**: FastAPI with Python 3.12+, uv for dependency management
- **Vector Database**: Qdrant for knowledge base storage and retrieval
- **Containerization**: Docker and Docker Compose

Expand Down Expand Up @@ -45,7 +45,7 @@ VCell-GSoC/
### Backend
- **Framework**: FastAPI
- **Language**: Python 3.12+
- **Dependency Management**: Poetry
- **Dependency Management**: uv
- **Database**: Qdrant Vector Database
- **AI/ML**: OpenAI API, LangChain
- **File Processing**: PyPDF, Markitdown
Expand Down Expand Up @@ -95,9 +95,9 @@ VCell-GSoC/
#### Backend Setup
```bash
cd backend
poetry install --no-root
poetry run uvicorn app.main:app --port 8000
# poetry run uvicorn app.main:app --reload
uv sync
uv run uvicorn app.main:app --port 8000
# uv run uvicorn app.main:app --reload
```

#### Frontend Setup
Expand Down
6 changes: 3 additions & 3 deletions SETUP.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Before you begin, ensure you have the following installed:
- **Node.js 18+** - For frontend development
- **Python 3.12+** - For backend development
- **Git** - For version control
- **Poetry** - For Python dependency management (install via `pip install poetry`)
- **[uv](https://docs.astral.sh/uv/)** - For Python dependency management (install via `curl -LsSf https://astral.sh/uv/install.sh | sh`)

## Initial Setup

Expand Down Expand Up @@ -205,8 +205,8 @@ docker run -d \

```bash
cd backend
poetry install --no-root
poetry run uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
uv sync
uv run uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
```

### 5.3 Start Frontend
Expand Down
17 changes: 8 additions & 9 deletions backend/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,25 @@ FROM python:3.12-slim

# 2. Set environment vars
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
POETRY_VIRTUALENVS_CREATE=false
PYTHONUNBUFFERED=1

# 3. Install Poetry
RUN pip install --no-cache-dir poetry
# 3. Install uv
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/

# 4. Set work directory
WORKDIR /app

# 5. Copy only pyproject + lock first for caching
COPY pyproject.toml poetry.lock* ./
COPY pyproject.toml uv.lock ./

# 6. Install dependencies (without virtualenvs, no-root to skip package install)
RUN poetry install --no-interaction --no-ansi --no-root
# 6. Install dependencies without installing the local project package.
RUN uv sync --frozen --no-install-project

# 8. Now copy the full project
COPY . .

# 9. Expose the FastAPI dev port
EXPOSE 8000

# 10. Run uvicorn in dev mode with reload
CMD ["sh", "-c", "poetry run uvicorn app.main:app --host 0.0.0.0 --port 8000"]
# 10. Run uvicorn without re-syncing on each container start.
CMD ["uv", "run", "--no-sync", "uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
10 changes: 5 additions & 5 deletions backend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ backend/
│ ├── schemas/ # Pydantic data models
│ └── utils/ # Utility functions
├── tests/ # Test suite
├── pyproject.toml # Poetry configuration
├── pyproject.toml # Project configuration
└── Dockerfile # Container configuration
```

Expand Down Expand Up @@ -65,7 +65,7 @@ backend/
## Tech Stack
- **Framework**: FastAPI 0.115+
- **Language**: Python 3.12+
- **Dependency Management**: Poetry
- **Dependency Management**: uv
- **Database**: Qdrant Vector Database
- **AI/ML**: OpenAI API, LangChain
- **File Processing**: PyPDF, Markitdown
Expand All @@ -77,7 +77,7 @@ backend/

### Prerequisites
- Python 3.12+
- Poetry
- [uv](https://docs.astral.sh/uv/)
- Docker (for Qdrant)

### Installation
Expand All @@ -89,7 +89,7 @@ backend/

2. **Install dependencies**
```bash
poetry install
uv sync
```

3. **Set up environment variables**
Expand All @@ -100,7 +100,7 @@ backend/

4. **Start the development server**
```bash
poetry run uvicorn app.main:app --reload
uv run uvicorn app.main:app --reload
```

### Using Docker
Expand Down
1 change: 1 addition & 0 deletions backend/app/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""VCell Backend Application"""
1 change: 1 addition & 0 deletions backend/app/schemas/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Pydantic schemas for VCell Backend"""
1 change: 1 addition & 0 deletions backend/app/utils/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Utility functions for VCell Backend"""
96 changes: 68 additions & 28 deletions backend/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,36 +1,76 @@
[tool.poetry]
[project]
name = "vcell-backend"
version = "0.1.0"
description = ""
authors = ["Kacem Mathlouthi <[email protected]>"]
authors = [{name = "Kacem Mathlouthi", email = "[email protected]"}]
readme = "README.md"
requires-python = ">=3.12,<3.14"
dependencies = [
"fastapi>=0.115.12,<0.116.0",
"uvicorn[standard]>=0.34.3,<0.35.0",
"pydantic-settings>=2.9.1,<3.0.0",
"httpx>=0.28.1,<0.29.0",
"openai>=1.84.0,<2.0.0",
"qdrant-client>=1.15.0,<2.0.0",
"langchain>=0.3.27,<0.4.0",
"langchain-text-splitters>=0.3.8,<0.4.0",
"langfuse>=3.2.4,<4.0.0",
"pypdf>=5.8.0,<6.0.0",
"pypdf2>=3.0.1,<4.0.0",
"python-multipart>=0.0.20,<0.1.0",
"markitdown[all]>=0.1.2,<0.2.0",
"notebook>=7.4.4,<8.0.0",
"ipykernel>=6.30.0,<7.0.0",
]

[tool.poetry.dependencies]
python = ">=3.12,<3.14"
fastapi = "^0.115.12"
uvicorn = {extras = ["standard"], version = "^0.34.3"}
pydantic-settings = "^2.9.1"
httpx = "^0.28.1"
black = "^25.1.0"
openai = "^1.84.0"
qdrant-client = "^1.15.0"
langchain = "^0.3.27"
pypdf = "^5.8.0"
pypdf2 = "^3.0.1"
python-multipart = "^0.0.20"
markitdown = {extras = ["all"], version = "^0.1.2"}
notebook = "^7.4.4"
ipykernel = "^6.30.0"
langfuse = "^3.2.4"
pytest = "^8.4.1"
pytest-asyncio = "^1.1.0"
[dependency-groups]
dev = [
"pytest>=8.4.1,<9.0.0",
"pytest-asyncio>=1.1.0,<2.0.0",
"ruff>=0.3.0,<1.0.0",
]

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.poetry.group.dev.dependencies]
pytest = "^8.4.0"
httpx = "^0.28.1"
pytest-asyncio = "^1.0.0"
[tool.uv]
managed = true

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
[tool.ruff]
line-length = 100
target-version = "py312"
exclude = [
".git",
".venv",
"__pycache__",
"*.egg-info",
".pytest_cache",
]

[tool.ruff.lint]
select = [
"E", # pycodestyle errors
"W", # pycodestyle warnings
"F", # Pyflakes
"I", # isort
"C", # flake8-comprehensions
"B", # flake8-bugbear
"UP", # pyupgrade
"ARG", # flake8-unused-arguments
"SIM", # flake8-simplify
]
ignore = [
"E501", # line too long (handled by formatter)
"W503", # line break before binary operator
"E203", # whitespace before ':'
]

[tool.ruff.lint.isort]
known-first-party = ["app"]
multi-line-string-mode = "multi"

[tool.pytest.ini_options]
asyncio_mode = "auto"
testpaths = ["app/tests"]
python_files = ["test_*.py"]
Loading