This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
- Install dependencies:
pip install -r requirements.txt - Run the app:
flask run(orgunicorn api.wsgi:app --log-file=- --log-level debug --preload --workers 1) - Run tests:
pytest - Run a single test:
pytest path/to/test_file.py::test_function_name - Run linting:
pylint api/ common/ db/ model/ services/ - Python environment: Miniconda with
conda activate py39_ohack_backend(Python 3.9.13)
The app is created via api/__init__.py:create_app(). Each API domain is a Blueprint registered there. The WSGI entrypoint is api/wsgi.py.
Each API domain lives in api/<domain>/ with a consistent structure:
<domain>_views.py— Flask Blueprint with route definitions. Routes use@cross_origin()and PropelAuth's@auth.require_userfor authentication.<domain>_service.py— Business logic called by views. Some older services live inservices/at the top level (hearts, users, volunteers, etc.).tests/— Tests for that domain.
API domains: messages, certificates, contact, github, hearts, judging, leaderboard, llm, newsletters, problemstatements, slack, store, teams, users, validate, volunteers.
db/interface.py— AbstractDatabaseInterfacebase class.db/firestore.py— Production implementation using Firebase Firestore.db/mem.py— In-memory implementation (enabled viaIN_MEMORY_DATABASE=Trueenv var).db/db.py— Singleton that selects the implementation and re-exports all DB operations as module-level functions. All service code imports fromdb.db.
Data classes (User, Hackathon, Nonprofit, ProblemStatement, JudgeAssignment, JudgeScore, JudgePanel, etc.) with serialize()/deserialize() methods for Firestore document conversion.
PropelAuth via common/auth.py. Routes get the authenticated user from @auth.require_user and org context from the X-Org-Id header.
common/utils/redis_cache.py — Redis with TTLCache fallback. Used via @cached_with_key() decorator.
common/log.py — Structured JSON logging with get_logger(), info(), debug(), warning(), error(), exception() helpers. Supports colored console output.
FLASK_APP=api, FLASK_RUN_PORT=6060, CLIENT_ORIGIN_URL, FIREBASE_CERT_CONFIG, OPENAI_API_KEY, PROPEL_AUTH_KEY, PROPEL_AUTH_URL, REDIS_URL (optional), IN_MEMORY_DATABASE (optional), ENVIRONMENT=test (for MockFirestore).
Deployed to Fly.io (fly.toml, app: backend-ohack, region: sjc). Uses gunicorn (Procfile). Port 6060.
- Tests live in
api/<domain>/tests/ortest/at the repo root. - The app has heavy external dependencies (Firestore, OpenAI, PropelAuth, Slack, PIL). Tests must pre-mock these modules in
sys.modulesbefore importing service code. ENVIRONMENT=testenables MockFirestore in the DB layer.
- Python 3.9.13 (Flask backend)
- Imports: Group standard library, then third-party, then local imports
- Types: Use type hints for function parameters and return values
- Naming: snake_case for variables/functions, PascalCase for classes
- Error handling: try/except with specific exceptions
- Linting: pylint (
.pylintrcdisables missing-module-docstring, missing-function-docstring, too-few-public-methods)