Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/OWASP/Nest/llms.txt

Use this file to discover all available pages before exploring further.

Overview

OWASP Nest helps you discover and connect with OWASP chapters around the world. With geocoded location data and proximity-based search, find your local chapter and get involved in the community.

Chapter Model

Chapters are repository-based entities with location intelligence:
backend/apps/owasp/models/chapter.py

Key Features

Geographic Data

Latitude/longitude coordinates for all chapters

Auto-Geocoding

AI-powered location detection from metadata

Regional Info

Country, region, postal code organization

Activity Tracking

Contribution data and engagement metrics

Chapter Attributes

Location Fields

name: str                      # Chapter name
country: str                   # Country name
region: str                    # State/province/region
postal_code: str               # Postal/ZIP code
latitude: float                # Geocoded latitude
longitude: float               # Geocoded longitude
suggested_location: str        # AI-generated location string

Chapter Metadata

level: str                     # Chapter level/status
currency: str                  # Local currency code
meetup_group: str             # Meetup.com group name
related_urls: list[str]       # Website, social links

Activity Data

contribution_data: dict        # Daily contribution counts
contribution_stats: dict       # Breakdown by activity type
created_at: datetime          # Chapter creation date
updated_at: datetime          # Last update

Interactive Map View

The chapters page features an interactive map showing all chapters:
// frontend/src/app/chapters/page.tsx
Map Features:
  • Cluster markers for dense regions
  • Click markers to view chapter details
  • Automatic user location detection
  • Proximity-based “chapters near you”
  • 400px height, full-width responsive design
The map loads up to 1000 chapters on the first page for comprehensive geographic coverage.
Find chapters near you with automatic IP-based location detection:
const searchParams = {
  aroundLatLngViaIP: true,  // Auto-detect user location
  indexName: 'chapters',
  hitsPerPage: 25
}

Location Filters

Filter chapters by geographic bounds:
GET /api/v0/chapters?latitude_gte=40&latitude_lte=45&longitude_gte=-75&longitude_lte=-70
Available Parameters:
  • latitude_gte - Minimum latitude
  • latitude_lte - Maximum latitude
  • longitude_gte - Minimum longitude
  • longitude_lte - Maximum longitude
  • country - Filter by country name
curl "https://nest.owasp.org/api/v0/chapters?country=United%20States&ordering=-updated_at"

Chapter API

List Chapters

GET /api/v0/chapters
Query Parameters:
  • country - Filter by country
  • latitude_gte, latitude_lte - Latitude bounds
  • longitude_gte, longitude_lte - Longitude bounds
  • ordering - Sort order
  • page - Page number
Sorting Options:
  • created_at / -created_at
  • updated_at / -updated_at
  • latitude / -latitude
  • longitude / -longitude
Example Response:
{
  "items": [
    {
      "key": "london",
      "name": "OWASP London",
      "latitude": 51.5074,
      "longitude": -0.1278,
      "created_at": "2024-01-15T10:30:00Z",
      "updated_at": "2024-03-01T14:22:00Z"
    }
  ],
  "count": 278,
  "next": "https://nest.owasp.org/api/v0/chapters?page=2"
}

Get Chapter Details

GET /api/v0/chapters/{chapter_key}
Example:
curl "https://nest.owasp.org/api/v0/chapters/london"
Response:
{
  "key": "london",
  "name": "OWASP London",
  "country": "United Kingdom",
  "region": "England",
  "latitude": 51.5074,
  "longitude": -0.1278,
  "leaders": [
    {
      "key": "sam",
      "name": "Sam Stepanyan"
    }
  ],
  "created_at": "2024-01-15T10:30:00Z",
  "updated_at": "2024-03-01T14:22:00Z"
}

Geocoding System

Chapters use AI-powered geocoding to convert metadata into coordinates:

Location Detection Process

  1. Metadata Extraction - Parse country, region, postal code from repository
  2. AI Location Suggestion - Generate suggested location string using OpenAI
  3. Geocoding - Convert location string to lat/lng coordinates
  4. Validation - Verify coordinates are valid and within expected bounds
# backend/apps/owasp/models/chapter.py:131
def generate_geo_location(self) -> None:
    """Add latitude and longitude data based on suggested location or geo string."""
    location = None
    if self.suggested_location and self.suggested_location != "None":
        location = get_location_coordinates(self.suggested_location)
    if location is None:
        location = get_location_coordinates(self.get_geo_string())
    
    if location:
        self.latitude = location.latitude
        self.longitude = location.longitude

AI-Generated Location Strings

Chapters use OpenAI to generate structured location strings:
# backend/apps/owasp/models/chapter.py:143
def generate_suggested_location(
    self,
    open_ai: OpenAi | None = None,
    max_tokens: int = 100,
) -> None:
    """Generate a suggested location using OpenAI."""
    prompt = Prompt.get_owasp_chapter_suggested_location()
    open_ai = open_ai or OpenAi()
    open_ai.set_input(self.get_geo_string())
    open_ai.set_max_tokens(max_tokens).set_prompt(prompt)
    suggested_location = open_ai.complete()
    self.suggested_location = suggested_location if suggested_location != "None" else ""

Geo String Format

The geo string combines chapter metadata:
def get_geo_string(self, *, include_name: bool = True) -> str:
    """Return a geo string for the chapter."""
    return join_values([
        self.name.replace("OWASP", "").strip() if include_name else "",
        self.country,
        self.postal_code,
    ], delimiter=", ")
Example: "London, United Kingdom, SW1A 1AA"

Active Chapters

Nest filters for active chapters with valid location data:
# Only chapters that are active and geocoded
Chapter.active_chapters.all()

# Count of active chapters
Chapter.active_chapters_count()
Requirements for Active Status:
  • is_active = True
  • latitude and longitude not null
  • OWASP repository is not empty

Chapter URLs

chapter.nest_key                    # "london" (without www-chapter- prefix)
chapter.nest_url                    # "/chapters/london"
chapter.get_absolute_url()          # Full URL with domain
Chapter keys are the repository name with the www-chapter- prefix removed.

Frontend Integration

Chapter Card Display

Chapter cards show:
  • Chapter name and location
  • Last updated timestamp
  • Top contributors
  • Social/related URLs
  • “View Details” action button

Search Experience

// Real-time search with Algolia
const { items: chapters, isLoaded, searchQuery, handleSearch } = 
  useSearchPage<Chapter>({
    indexName: 'chapters',
    pageTitle: 'OWASP Chapters'
  })

Map Wrapper Component

<ChapterMapWrapper
  geoLocData={searchQuery ? chapters : allChapters}
  showLocal={true}
  showLocationSharing={true}
  style={{
    height: '400px',
    width: '100%',
    zIndex: '0',
    borderRadius: '0.5rem',
    boxShadow: '0 4px 6px rgba(0, 0, 0, 0.1)'
  }}
/>

Slack Integration

Query chapters via the Slack bot:
/chapters [search query]
Examples:
/chapters                    # Show all chapters
/chapters london            # Search for London chapter
/chapters start             # Interactive start message
See Slack Bot for more commands.

Database Indexes

Optimized queries with indexes:
indexes = [
    models.Index(fields=["-created_at"], name="chapter_created_at_desc_idx"),
    models.Index(fields=["-updated_at"], name="chapter_updated_at_desc_idx"),
]

Code Reference

Key implementation files:
  • Model: backend/apps/owasp/models/chapter.py:19
  • API: backend/apps/api/rest/v0/chapter.py:17
  • Manager: backend/apps/owasp/models/managers/chapter.py
  • Frontend: frontend/src/app/chapters/page.tsx:14
  • Map Component: frontend/src/components/ChapterMapWrapper.tsx

AI Integration

Chapters are indexed for AI-powered discovery:
backend/apps/ai/common/extractors/chapter.py
  • Search - Geographic chapter search
  • Events - Find events hosted by chapters
  • Slack Bot - Query chapters via /chapters