Antares Web is a web platform (REST API + React UI) by RTE for managing
Antares Simulator studies. It is a monorepo with a
Python/FastAPI backend in antarest/ and a React/TypeScript frontend in webapp/.
- Backend: Python 3.11, FastAPI, Pydantic v2, SQLAlchemy 2 + Alembic, Celery/Redis,
managed with uv (
uv sync,uv run ...). - Frontend: Node 22.13, React 19, Vite, Redux Toolkit, TanStack Query/Router, MUI, vitest.
- DB: SQLite for local/desktop, PostgreSQL for production.
Backend (run from repo root):
uv sync # install deps (incl. dev)
uv run pytest -n auto # full test suite (parallel)
uv run pytest tests/study/test_x.py::test_name # a single test
uv run ruff check antarest/ tests/ --fix # lint + autofix
uv run ruff format antarest/ tests/ # format (line-length 120, double quotes)
uv run mypy # strict type check (config in pyproject.toml)Frontend (run from webapp/):
npm install
npm run dev # Vite dev server (port 3000)
npm run test # vitest (runs with TZ=UTC)
npm run test -- src/path/File.test.tsx # a single test file
npm run lint # tsc --noEmit + eslint
npm run build # tsc + vite buildRun the backend dev server:
python antarest/main.py -c resources/application.yaml --auto-upgrade-db --no-front
Full checks (pytest + mypy + ruff) can be run via scripts/linter.sh. pre-commit hooks
enforce mypy, ruff, and license headers.
Entry points (see docs/architecture.md):
antarest/main.py— standalone dev server (single worker).antarest/wsgi.py— gunicorn/uvicorn app for production.antarest/gui.py— desktop application.antarest/tools/admin.py— admin CLI.- worker services (
antarest/worker/) — remote background jobs (e.g. unzip results).
Module layout: each feature package under antarest/ (e.g. study/, login/,
launcher/, matrixstore/, core/) follows a consistent structure:
service.py— main service / facade.web.py(or aweb/dir of blueprints) — FastAPI REST endpoints.main.py—build_<service>()factory wiring dependencies.model.py— business objects, DTOs, and DB entities (may be a directory).repository.py— DB query helpers for the entities.business/,dao/,adapters.py,utils.py— supporting logic.
The study/ package is the core domain (largest module): study storage lives in
study/storage/ (raw studies, variant studies, upgraders), and DAOs in study/dao/.
Stack details: TanStack Router (file-based) + TanStack Query, Zod, Redux,
react-hook-form, MUI (Emotion), i18next, Axios, Notistack, Vite, Vitest. Path alias
@/* → src/*.
Never edit src/routeTree.gen.ts — generated by the TanStack Router plugin.
Source layout (webapp/src/):
routes/— file-based routing:__root.tsx,_authenticated/(auth layout guard),route.tsx= layout,index.tsx= index route,$param/= dynamic segment. Dash-prefixed folders (-components/,-hooks/,-shared/) are colocated non-route code.components/— shared library:Form/,fieldEditors/,dialogs/,page/,Matrix/, etc.services/api/— axios wrappers per domain; shared client inservices/api/client.ts(token injection + 401 logout via interceptors). Server responses are snake_case, so convert DTOs to camelCase models (helpers inservices/utils/) using Zod.queries/<domain>/— TanStack Query:keys.ts(key factory),queries.ts,mutations.ts.redux/— global client state (ducks inredux/ducks/, selectors inredux/selectors.ts, typed hooks inredux/hooks/). Prefer TanStack Query for new server state; Redux is for app-wide client state (auth, UI).hooks/,utils/,theme/,types/— app-wide hooks, helpers, MUI theme, ambient types.
Conventions :
- Style with the
sxprop, notstyled()(project practice). Usetheme.vars.palette, nevertheme.palettedirectly; read the color mode via theuseThemeColorSchemehook. - Imports: from
@mui/materialroot (no subpaths); React types asReact.ReactNode(not named type imports fromreact);import typefor type-only imports;import i18n from "@/i18n", never fromi18next. - No non-null assertions (
!); noconsole.*(stripped in prod — surface errors to users viauseEnqueueErrorSnackbar()). - i18n: keys in
public/locales/{en,fr}/main.json, dot-namespaced (e.g.global.save);useTranslation()in components. Always add bothenandfrtranslations. - Forms: use the
<Form>component (components/Form/submit error snackbars, and undo/redo. Build fields with the*FEeditors incomponents/fieldEditors/(RHF-aware via thereactHookFormSupportHOC); validators inutils/validation/. - Naming: PascalCase for component files/dirs.
Frontend tests: colocated in __tests__/ folders with jsdom and globals, setup
in src/tests/setup.ts. Use test() not it(). Testing Library + user-event; no
MSW — mock API modules with vi.mock.
- License headers: every
.py/.ts/.tsxfile underantarest/,tests/, andwebapp/must start with the MPL-2.0 header (see top ofantarest/main.py). It is checked in pre-commit and CI viascripts/license_checker_and_adder.py. - Typing: mypy runs in
strictmode withexplicit-overriderequired; all backend code must be fully type-hinted. - Database changes: modify SQLAlchemy models (e.g.
study/model.py), register new model files inantarest/dbmodel.py, then generate a migration withbash scripts/create_db_migration.sh "<message>"(needsANTAREST_CONFset). Integration tests intests/integrationexercise the real Alembic migration path. - Commits & PR titles: Conventional Commits enforced by commitlint. Scope is
required and must be lower/kebab-case, e.g.
feat(study): ...,fix(ui): .... - Branching: git-flow.
devis the default branch; branch asfeat/...,fix/...,docs/....
- Backend tests are in
tests/, mirroring theantarest/package layout; shared fixtures are intests/conftest*.py.testcontainersis used for Postgres-backed tests. - Frontend tests are colocated as
*.test.ts(x)and run under vitest withTZ=UTC.