A Python based local web application for uploading MODAQ files to S3 with progress tracking, duplicate detection, and configuration.
- Drag-and-drop file upload - Select individual files or entire folders
- MCAP timestamp extraction - Automatically extracts timestamps using modaq_toolkit
- Hive-partitioned S3 paths - Files are organized by
year/month/day/hour/minute - Duplicate detection - Checks if files already exist in S3 before uploading
- Real-time progress - Server-Sent Events (SSE) for live upload progress
- S3 file browser - Navigate and search uploaded files
- Application updates - Built-in git pull and pip install functionality
- NLR branding - Official NLR color palette and styling
- Python 3.11 or higher
- AWS credentials configured in
~/.aws/credentials - Access to an S3 bucket
- Clone the repository:
git clone <repository-url>
cd modaq_upload- Create a virtual environment:
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate- Install Python dependencies:
pip install -r requirements.txt- Install frontend dependencies and build the UI:
cd frontend && npm install && npm run build && cd ..python app.pyThe application will be available at http://localhost:5000.
Run the Flask backend and Vite frontend separately for hot-reload during development:
Terminal 1: Flask API (port 5000):
python app.pyTerminal 2: Vite dev server (port 3000):
cd frontend && npm run devOpen http://localhost:3000. The Vite server proxies /api requests to Flask.
After making frontend changes you're happy with, rebuild for production:
cd frontend && npm run buildFor production use on a Linux machine, use the automated installation script which sets up a systemd service with Gunicorn.
cd deploy
sudo python3 install.pyThis will:
- Install system dependencies (python3, python3-venv, git)
- Create a
modaqsystem user - Copy the application to
/opt/modaq-upload - Create a Python virtual environment and install dependencies
- Set up logging at
/var/log/modaq-upload - Install and enable a systemd service
- Configure AWS credentials for the modaq user:
sudo -u modaq aws configure --profile default- Edit the application settings:
sudo nano /opt/modaq-upload/settings.json- The application runs at
http://localhost:8080
Check status
sudo systemctl status modaq-uploadView logs
sudo journalctl -u modaq-upload -fRestart after config changes
sudo systemctl restart modaq-uploadStop the service
sudo systemctl stop modaq-uploadcd deploy
sudo python3 uninstall.pySettings can be configured in two ways:
Create a .env file in the project root:
cp .env.example .envEdit .env with your settings:
# AWS Profile name from ~/.aws/credentials
MODAQ_AWS_PROFILE=<profile_name>
# AWS Region
MODAQ_AWS_REGION=<AWS region, e.g. us-west-2>
# S3 Bucket name for uploads
MODAQ_S3_BUCKET=<your-bucket-name>
# Default folder to open when selecting files (optional)
MODAQ_DEFAULT_UPLOAD_FOLDER=</path/to/mcap/files>
# Custom display name shown in the header (optional)
MODAQ_DISPLAY_NAME=<My Custom Name>Environment variables take precedence over settings configured in the web UI.
- Navigate to the Settings page
- Select your AWS profile from the dropdown
- Enter your S3 bucket name
- Click Test Connection to verify access
- Click Save Settings
Settings are saved to settings.json (gitignored).
See Application Guide: Upload below for a walkthrough.
See Application Guide: Browse Uploaded Files below.
See Application Guide: Updating the Software below.
The Upload page walks you through uploading files in four steps: Select → Review → Upload → Complete.
- Navigate to the folder containing your MCAP files using the file browser. Quick Links on the left give fast access to common locations.
- The browser shows each subfolder's upload status: data file count, log file count, and how many have already been uploaded to S3.
- Check or uncheck folders to include or exclude them. Use Select All / None or search to filter.
- Click Upload N files to proceed to the Review step, where you can inspect the per-file S3 destination paths before committing.
- Already-uploaded files are skipped; no duplicates are created.
For more than 500 files, use Large Folder Upload instead.
The Large Folder Upload page syncs an entire folder tree to S3 without per-file analysis. Use this when you have 500+ files and don't need to inspect each file's timestamp individually.
- Navigate to the root folder you want to sync.
- Click Select This Folder to confirm.
- The folder structure is copied to S3 as-is. Already-uploaded files are skipped.
The Browse Uploaded Files page lets you navigate the contents of your S3 bucket directly from the app.
- Click any folder to drill down into it.
- Use the breadcrumb trail at the top to navigate back up.
- This is useful for verifying that uploads landed in the correct location.
The History page keeps a record of every upload session run from this machine.
- Upload History tab: each session's date, file count, data transferred, transfer speed, and outcome (completed / skipped / failed). Click any row to expand the per-file breakdown. Use CSV to export a session log.
- Event Log tab: application events for troubleshooting.
The running totals at the top (files uploaded, total data, failed, sessions) summarise all sessions.
The Clear Hard Drive page removes local files that have already been uploaded to S3. Files are verified against S3 before any deletion.
- Navigate to the folder you want to clean up.
- The browser shows how many files are uploaded (deletable) vs not yet uploaded.
- Only uploaded files are deleted; files not yet in S3 are not touched.
- Click Clear N files and confirm to proceed through the workflow (Select → Review → Confirm → Clear → Complete).
The Settings page controls the AWS connection used for all uploads and browsing.
- AWS Profile: profile from
~/.aws/credentialsto use. - AWS Region: region of your S3 bucket.
- S3 Bucket: bucket files are uploaded to.
- Default Upload Folder: pre-populates the file browser on the Upload page.
- Display Name: title shown in the application header.
- Log Directory: where upload history logs are stored.
Fields marked Locked: set by environment variable are controlled by your .env file and cannot be changed from the UI (see Configuration).
From v1.1 onwards, updates can be applied from within the app.
Option A: via Settings:
- Click Settings in the navigation bar.
- Scroll down to the Software Update section.
- Click Check for updates.
- If updates are available, click Update Application. This pulls the latest code, reinstalls Python dependencies, and updates
modaq_toolkit. - Restart the application after the update completes (
Ctrl+Cthenpython app.py, or restart the systemd service).
Option B: via the About modal:
- Click the version badge (e.g. v1.1.0) in the navigation bar to open the About modal.
- Expand the Software Update section and follow the same steps.
If you are running a version prior to v1.1, the in-app updater is not available. Update manually from the terminal:
cd modaq_upload
git pull
source venv/bin/activate # On Windows: venv\Scripts\activate
pip install -r requirements.txt
cd frontend && npm install && npm run build && cd ..Then restart the application:
python app.pyOr, if running as a systemd service:
sudo systemctl restart modaq-uploadFiles are uploaded to S3 using a Hive-partitioned path format:
year=YYYY/month=MM/day=DD/hour=HH/minute=M0/filename.mcap
Where:
- Minutes are rounded to 10-minute buckets (00, 10, 20, 30, 40, 50)
- Timestamps are extracted from the MCAP file data
pytest tests/ -vWith coverage:
pytest tests/ --cov=app --cov-report=htmlruff check app/ tests/
ruff format app/ tests/mypy app/pip install -r requirements-dev.txtcd frontend && npm run lint # Check
cd frontend && npm run lint:fix # Auto-fixcd frontend && npm run typecheckcd frontend && npm run test # Run all JS tests
cd frontend && npm run test:watch # Watch mode
cd frontend && npm run test:coverage # With coverage reportcd frontend && npm run check # Biome + tsc + VitestSee docs/ARCHITECTURE.md for project structure and API endpoint reference.
BSD 3-Clause License. See LICENSE for details.






