Skip to main content

Overview

The OWASP Nest backend is built with Django 6.0 and Python 3.13, using modern Python frameworks and libraries for API development, search, and AI features.

Tech Stack

Django 6.0

Web framework

Django Ninja

REST API framework

Strawberry

GraphQL library

PostgreSQL

Primary database

Redis

Cache & queue

Poetry

Dependency management

Project Structure

backend/
├── apps/                   # Django applications
│   ├── ai/                # AI agent and vector search
│   ├── api/               # REST and GraphQL endpoints
│   ├── common/            # Shared utilities
│   ├── core/              # Core Django app
│   ├── github/            # GitHub integration
│   ├── mentorship/        # Mentorship features
│   ├── nest/              # Nest-specific models
│   ├── owasp/             # OWASP data models
│   ├── sitemap/           # Sitemap generation
│   └── slack/             # NestBot integration
├── data/                  # Database fixtures
├── settings/              # Django configurations
│   ├── base.py           # Base settings
│   ├── local.py          # Local development
│   ├── production.py     # Production
│   └── test.py           # Testing
├── tests/                 # Test files
├── manage.py              # Django management
├── pyproject.toml         # Poetry configuration
└── .env                   # Environment variables

Development Setup

Prerequisites

Ensure you have completed the local development setup first.

Dependencies

Dependencies are managed with Poetry and defined in pyproject.toml:
pyproject.toml
django = "^6.0"
django-configurations = "^2.5.1"
django-ninja = "^1.5.3"
strawberry-graphql = { extras = ["django"], version = "^0.291.0" }
psycopg2-binary = "^2.9.9"
redis = "^6.0.0"
gunicorn = "^25.0.0"

Update Dependencies

make update-backend-dependencies
This runs poetry update to update all backend dependencies.

Common Commands

# Create migrations
make migrations

# Apply migrations
make migrate

# Create empty migration
APP_NAME=owasp make migrations-empty

# Merge conflicting migrations
make merge-migrations

Django Apps

AI App

Provides AI-powered features using LangChain and OpenAI:
LangGraph Agent (apps/ai/agent/)
  • Natural language query processing
  • Multi-step reasoning with tools
  • RAG (Retrieval-Augmented Generation)
  • Context-aware responses
Example usage:
from apps.ai.agent import Agent

agent = Agent()
response = agent.query("Find beginner-friendly Python projects")
pgvector Integration
  • Document chunking and embedding
  • Semantic similarity search
  • Context retrieval for RAG
Models:
  • Embedding - Vector representations
  • Context - Document contexts
  • Chunk - Text chunks
# Generate embeddings
python manage.py generate_embeddings

# Chunk documents
python manage.py chunk_documents

# Update contexts
python manage.py update_contexts

API App

Provides REST and GraphQL endpoints:
Django Ninja (apps/api/rest/)Base URL: /api/v0/
apps/api/rest/projects.py
from ninja import Router
from apps.owasp.models import Project

router = Router()

@router.get("/projects/")
def list_projects(request, limit: int = 10):
    projects = Project.objects.all()[:limit]
    return {"projects": [p.to_dict() for p in projects]}
Features:
  • Automatic OpenAPI docs at /api/docs
  • Pydantic schema validation
  • Built-in filtering and pagination

GitHub App

Syncs data from GitHub:
Key models in apps/github/models/:
  • GitHubOrganization - OWASP and related orgs
  • GitHubRepository - Project repositories
  • GitHubIssue - Issues and contribution opportunities
  • GitHubUser - User profiles
  • GitHubPullRequest - Pull requests
# Update OWASP organization
make github-update-owasp-organization

# Add related repositories
make github-add-related-repositories

# Update users
make github-update-users

# Enrich issues
make github-enrich-issues
Uses PyGithub for GitHub API access:
from github import Github
from django.conf import settings

g = Github(settings.GITHUB_TOKEN)
org = g.get_organization("OWASP")
repos = org.get_repos()

OWASP App

Manages OWASP-specific data:
Project Model (apps/owasp/models.py)Fields:
  • name - Project name
  • description - Project description
  • level - Project level (Lab, Production, Flagship)
  • type - Project type (Code, Documentation, Tool)
  • leaders_raw - Project leaders (JSON)
  • repositories - Related GitHub repos (M2M)
  • url - Project website
Management commands:
make owasp-scrape-projects
make owasp-enrich-projects
make owasp-aggregate-projects

Slack App

NestBot Slack integration:
Located in apps/slack/commands/:
  • /nest-find-issues - Search contribution opportunities
  • /nest-find-projects - Search OWASP projects
  • /nest-help - Get help
Example:
apps/slack/commands/find_projects.py
from slack_bolt import Ack, Respond

def handle_find_projects(ack: Ack, respond: Respond, command: dict):
    ack()
    query = command["text"]
    # Search projects...
    respond(f"Found projects matching: {query}")
Located in apps/slack/events/:
  • app_mention - Handle @NestBot mentions
  • message - Handle DMs
Configuration:
DJANGO_SLACK_BOT_TOKEN=<your-bot-token>
DJANGO_SLACK_SIGNING_SECRET=<your-signing-secret>
make slack-sync-data
Syncs:
  • User profiles
  • Channel information
  • Message history

Configuration

Django Settings

Settings are organized using django-configurations:
base.py - Shared settings
settings/base.py
from configurations import Configuration

class Base(Configuration):
    DEBUG = False
    ALLOWED_HOSTS = []
    
    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        # ...
        'apps.ai',
        'apps.api',
        'apps.github',
        # ...
    ]

Environment Variables

Key variables in backend/.env:
.env
# Django
DJANGO_CONFIGURATION=Local
DJANGO_SECRET_KEY=<secret-key>
DJANGO_ALLOWED_HOSTS=localhost,127.0.0.1

# Database
DJANGO_DB_HOST=db
DJANGO_DB_NAME=nest_db_dev
DJANGO_DB_USER=nest_user_dev
DJANGO_DB_PASSWORD=nest_user_dev_password
DJANGO_DB_PORT=5432

# Redis
DJANGO_REDIS_HOST=cache
DJANGO_REDIS_PASSWORD=nest-cache-password

# Algolia
DJANGO_ALGOLIA_APPLICATION_ID=<app-id>
DJANGO_ALGOLIA_WRITE_API_KEY=<api-key>

# GitHub
GITHUB_TOKEN=<github-token>

# OpenAI
DJANGO_OPEN_AI_SECRET_KEY=<openai-key>

# Slack
DJANGO_SLACK_BOT_TOKEN=<bot-token>
DJANGO_SLACK_SIGNING_SECRET=<signing-secret>

# Sentry
DJANGO_SENTRY_DSN=<sentry-dsn>
See Environment Variables for full reference.

Testing

Test Configuration

Tests use pytest with Django plugin:
pyproject.toml
[tool.pytest]
ini_options.DJANGO_CONFIGURATION = "Test"
ini_options.DJANGO_SETTINGS_MODULE = "settings.test"
ini_options.addopts = [
  "--cov-config=pyproject.toml",
  "--cov-fail-under=95",
  "--cov-report=term-missing",
  "--cov=.",
  "--numprocesses=auto",
]

Running Tests

make test-backend

Writing Tests

tests/test_models.py
import pytest
from apps.owasp.models import Project

@pytest.mark.django_db
def test_create_project():
    project = Project.objects.create(
        name="Test Project",
        description="A test project",
        level="Lab",
    )
    assert project.name == "Test Project"
    assert project.level == "Lab"

Code Quality

Linting & Formatting

make check-backend
Pre-commit hooks (backend/.pre-commit-config.yaml):
  • Ruff - Python linter and formatter
  • mypy - Type checking
  • djlint - Django template linting

Ruff Configuration

pyproject.toml
[tool.ruff]
target-version = "py313"
line-length = 99
lint.select = ["ALL"]
lint.ignore = [
  "ANN",     # Type annotations
  "D407",    # Dashed underlines
  "COM812",  # Trailing commas
]

Database Management

Migrations

1

Create Migration

make migrations
2

Review Migration

# Check migration file
cat backend/apps/owasp/migrations/0001_initial.py
3

Apply Migration

make migrate

Database Shell

# Django shell
make django-shell

# PostgreSQL shell
make shell-db
Example queries:
# Django shell
from apps.owasp.models import Project
Project.objects.filter(level="Flagship").count()

Background Jobs

Django RQ

Background tasks use Redis Queue:
apps/ai/tasks.py
from django_rq import job

@job('ai')
def generate_embeddings(document_id):
    # Process document...
    pass
Enqueue jobs:
from apps.ai.tasks import generate_embeddings
generate_embeddings.delay(document_id=123)
Worker runs automatically via docker-compose/local/compose.yaml:
worker:
  command: python manage.py rqworker ai --with-scheduler

Debugging

Django Debug Toolbar

Enabled in local development:
  1. Visit any page
  2. Click debug toolbar on right side
  3. View SQL queries, cache hits, etc.

Python Debugger

import pdb; pdb.set_trace()

Logs

# Backend logs
docker logs -f nest-backend

# Worker logs
docker logs -f nest-worker

# Database logs
docker logs -f nest-db

Next Steps

Frontend Development

Learn about Next.js frontend development

Testing Guide

Write and run tests

API Reference

Explore API endpoints

Contributing

Contribution guidelines

Build docs developers (and LLMs) love