PDataViewer is a React and FastAPI web application that lets researchers explore the Parkinson’s disease data landscape, compare data availability across cohorts, and identify datasets suited to their research needs.
- PDataViewer
Data collected in cohort studies lay the groundwork for a wide range of Parkinson’s disease research. PDataViewer provides an overview of this data landscape and helps researchers identify cohort datasets suited to their research questions.
Major Parkinson’s disease cohort datasets were accessed and curated in a data-driven manner with the aim of:
- Characterizing their underlying data.
- Assessing the quantity and availability of data.
- Evaluating interoperability across distinct cohort datasets.
The repository contains a React + TypeScript frontend built with Vite, a Python FastAPI backend, and supporting container and deployment files.
PDataViewer/
├── backend/
│ ├── src/
│ │ └── pdataviewer/
│ │ ├── api/
│ │ │ ├── dependencies/
│ │ │ ├── routers/
│ │ │ ├── services/
│ │ │ ├── tasks/
│ │ │ ├── config.py
│ │ │ ├── main.py
│ │ │ ├── schemas.py
│ │ │ └── upload_utils.py
│ │ ├── database/
│ │ │ ├── models/
│ │ │ ├── repositories/
│ │ │ ├── administration.py
│ │ │ ├── import_utils.py
│ │ │ └── typeddicts.py
│ │ └── preprocessing/
│ │ ├── biomarkers.py
│ │ ├── common.py
│ │ └── longitudinal.py
│ ├── data/
│ ├── Dockerfile
│ ├── pyproject.toml
│ └── uv.lock
├── frontend/
│ ├── public/
│ ├── src/
│ │ ├── app/
│ │ ├── components/
│ │ ├── features/
│ │ │ ├── biomarkers/
│ │ │ ├── cohorts/
│ │ │ ├── contact-us/
│ │ │ ├── home/
│ │ │ ├── longitudinal/
│ │ │ ├── mappings/
│ │ │ └── study-picker/
│ │ ├── hooks/
│ │ ├── lib/
│ │ ├── index.css
│ │ └── main.tsx
│ ├── Dockerfile.dev
│ ├── Dockerfile.prod
│ ├── index.html
│ ├── package.json
│ └── vite.config.ts
├── docker-compose.yml
└── README.md
The running backend application is located under:
backend/src/pdataviewer/api/
Database models and repositories are located under:
backend/src/pdataviewer/database/
The preprocessing package is an offline workflow used to generate biomarker and longitudinal import files. It is not part of the running API.
The frontend uses React Router for navigation, TanStack Query for server state, and a feature-oriented structure. See frontend/README.md for frontend-specific development instructions.
For local development:
- Python >=3.14, <3.15
- uv
- Node.js 26 (recommended; the frontend also supports the versions listed in its
package.jsonenginesfield) - npm
- Git
- PostgreSQL 18
- A compatible Keycloak instance for authenticated endpoints
For containerized deployment:
- Docker
- Docker Compose
git clone https://github.com/SCAI-BIO/PDataViewer
cd PDataViewerConsult the uv installation documentation before installing the backend dependencies.
From the repository root:
cd backend
uv sync --lockedThis creates a virtual environment and installs the PDataViewer backend package and its development dependencies from uv.lock.
Install Node.js 26 and then run:
cd frontend
npm ciThe backend reads configuration from environment variables. For local development, create a .env file inside the backend directory.
Example:
POSTGRES_USER=testuser
POSTGRES_PASSWORD=testpass
POSTGRES_HOST=localhost
POSTGRES_PORT=5432
POSTGRES_DB=testdb
KEYCLOAK_URL=http://localhost:8080
KEYCLOAK_REALM=myrealm
KEYCLOAK_CLIENT_ID=pdataviewer-api
ALLOWED_ORIGINS='["http://localhost:5173","http://localhost:8080"]'ALLOWED_ORIGINS must be a valid JSON array of origin strings. The example allows the Vite development server (5173) and a locally served Nginx production frontend (8080). Adapt these origins to your actual deployment.
Do not commit backend .env files containing credentials. Environment-specific values should be supplied through local environment variables, Docker, Docker Compose, Kubernetes, or Helm.
Vite embeds public VITE_* configuration into the JavaScript bundle at build time. The React frontend currently expects the following variable:
| Variable | Purpose |
|---|---|
VITE_API_URL |
Base URL for the FastAPI backend; required for the production Docker build |
For local development, create frontend/.env.local:
VITE_API_URL=/apiWith the configured Vite development proxy, /api requests are forwarded to the local backend (typically http://localhost:5000). The proxy works only during Vite development; it is not available in the Nginx production image. A production /api URL requires an equivalent Nginx or ingress reverse-proxy route; otherwise, build with a browser-accessible absolute API URL.
GitHub Actions supplies VITE_API_URL to the production frontend Docker build using a repository variable and a Docker build argument. Updating a runtime container environment variable does not change a URL already compiled into the frontend.
The Google Analytics measurement ID is currently configured in the frontend analytics module rather than read from an environment variable. Its script is loaded after explicit consent. A measurement ID is public, but credentials must never be put in VITE_* variables.
Start the backend API on port 5000:
cd backend
uv run uvicorn pdataviewer.api.main:app --reload --port 5000The API is available at:
http://localhost:5000
Swagger documentation is available at:
http://localhost:5000/docs
The current API version is available at:
http://localhost:5000/version
The application creates missing database tables during startup. Existing database schema changes require an explicit migration or manual schema recreation.
The preprocessing pipelines generate files that can subsequently be imported through the backend API.
Run biomarker preprocessing:
cd backend
uv run python -m pdataviewer.preprocessing.biomarkersRun longitudinal preprocessing:
cd backend
uv run python -m pdataviewer.preprocessing.longitudinalBy default, the preprocessing pipelines read and write data under:
backend/data/
Patient-level source data and generated processed files are excluded from the production backend image.
From the repository root, build the backend image:
docker build \
-f backend/Dockerfile \
-t pdataviewer-backend:local \
backendOn PowerShell:
docker build `
-f backend/Dockerfile `
-t pdataviewer-backend:local `
backendStart the container with the backend environment file:
docker run --rm \
--name pdataviewer-backend \
--env-file backend/.env \
-p 8000:80 \
pdataviewer-backend:localOn PowerShell:
docker run --rm `
--name pdataviewer-backend `
--env-file backend/.env `
-p 8000:80 `
pdataviewer-backend:localThe API is available at localhost:8000, with Swagger documentation at localhost:8000/docs.
Inside a container, localhost refers to the container itself. When PostgreSQL runs directly on the host machine, use:
POSTGRES_HOST=host.docker.internalWhen PostgreSQL runs in another container on the same Docker network, use its container or service name:
POSTGRES_HOST=pdataviewer-postgresFor example:
docker network create pdataviewer
docker network connect \
pdataviewer \
pdataviewer-postgres
docker run --rm \
--name pdataviewer-backend \
--network pdataviewer \
--env-file backend/.env \
-e POSTGRES_HOST=pdataviewer-postgres \
-p 8000:80 \
pdataviewer-backend:localFrom the repository root, start the Vite development server:
cd frontend
npm ci
npm run devThe web application is typically available at localhost:5173. Configure frontend/.env.local as described above, and start the FastAPI backend for data-dependent features.
From the repository root, build the production frontend image:
docker build \
-f frontend/Dockerfile.prod \
--build-arg VITE_API_URL=http://localhost:8000 \
-t pdataviewer-frontend:local \
frontendOn PowerShell:
docker build `
-f frontend/Dockerfile.prod `
--build-arg VITE_API_URL=http://localhost:8000 `
-t pdataviewer-frontend:local `
frontendStart the container:
docker run --rm \
--name pdataviewer-frontend \
-p 8080:80 \
pdataviewer-frontend:localThe application is available at localhost:8080. This example assumes the backend is accessible from the browser at http://localhost:8000 and allows the frontend's origin (http://localhost:8080) in backend CORS settings. Change the build argument for your environment. The production image serves static files using Nginx.
The API and web application can be deployed together with Docker Compose. Before using a Compose configuration created for Angular, ensure it has been migrated to the React Dockerfile, correct frontend port, backend configuration, and build-time VITE_API_URL. In particular, Vite's development proxy is not automatically present in a production Nginx container.
Verify that Docker Compose is installed:
docker compose versionFrom the repository root, build and start the services:
docker compose up --buildVerify that the containers are running:
docker compose psThe ports exposed by Docker Compose are defined in docker-compose.yml. In the default local configuration, the web application and API are available through their configured frontend and backend ports.
Stop the services with:
docker compose downThe frontend defines one command for CI-compatible linting, testing, type checking, and production bundling:
cd frontend
npm run checkThis runs lint:ci (Oxlint with warnings denied), test:run (Vitest once), and build (tsc -b && vite build). Individual checks can also be run with npm run lint, npm run typecheck, npm run test:run, and npm run build. The frontend workflow can use the same npm run check command.
The backend uses Ruff for linting.
cd backend
uv run ruff check .Apply safe automatic fixes:
uv run ruff check . --fixDisplay linting statistics:
uv run ruff check . --statisticsVerify that all backend Python modules compile:
cd backend
uv run python -m compileall srcThe backend package can also be built locally:
cd backend
uv buildBuild artifacts are created under:
backend/dist/
Release images are published to the GitHub Container Registry:
ghcr.io/scai-bio/pdataviewer/frontend:<version>
ghcr.io/scai-bio/pdataviewer/backend:<version>
For example:
docker pull ghcr.io/scai-bio/pdataviewer/frontend:<version>
docker pull ghcr.io/scai-bio/pdataviewer/backend:<version>Run the published backend image with an environment file:
docker run --rm \
--name pdataviewer-backend \
--env-file backend/.env \
-p 8000:80 \
ghcr.io/scai-bio/pdataviewer/backend:<version>The release workflow currently publishes versioned tags. Do not assume a latest tag exists unless it is explicitly configured in the image metadata action.