This repository is intended to be deployed on a server as a small Flask web application for running the OneStopParallel scheduler through a browser.
Users can:
- upload an input DAG file and a machine description file
- choose one or more schedulers
- run the native
ospexecutable through the web UI - compare scheduling results in a table
- download the generated schedule files
The app has two main parts:
backend.py: Flask application that serves the UI and runs the OSP executabletemplates/andstatic/: frontend assets for the upload form, scheduler picker, and results table
At runtime, the backend:
- receives uploaded input files
- stores them in a temporary working directory
- executes the compiled
ospbinary - parses the executable output into JSON
- returns result rows and generated schedule files to the browser
The backend expects the OneStopParallel executable at:
third_party/OneStopParallel/build/apps/osp
.
├── backend.py
├── templates/
│ └── index.html
├── static/
│ ├── script.js
│ ├── schedulers.json
│ └── styles.css
├── data/
│ └── sample input files
└── third_party/
└── OneStopParallel/
You need:
- Python 3.10+ recommended
gitcmake- a C++ toolchain capable of building OneStopParallel
Python packages used by the backend:
flaskflask-corspandasgunicornfor production deployment
Example install:
python3 -m venv .venv
source .venv/bin/activate
pip install flask flask-cors pandas gunicornClone the repository together with its submodule:
git clone --recurse-submodules <your-repo-url>
cd OSP-OnlineServicePortalIf you already cloned it without submodules:
git submodule update --init --recursiveBuild the native executable in the expected location:
cd third_party/OneStopParallel
mkdir -p build
cd build
cmake ..
make -j"$(nproc)"After a successful build, this file should exist:
third_party/OneStopParallel/build/apps/ospFrom the repository root:
python3 -m venv .venv
source .venv/bin/activate
pip install flask flask-cors pandas gunicornThis project is designed to be run on a Linux server, typically behind Gunicorn and optionally behind a reverse proxy such as Nginx.
The Flask app object is exposed as backend:app, so Gunicorn should be started
from the repository root.
Example production command:
gunicorn backend:app \
--bind 0.0.0.0:8001 \
--workers 4 \
--timeout 43200 \
--daemon \
--access-logfile access.log \
--error-logfile error.log \
--capture-output \
--log-level infoThis is a valid way to run the application in production.
Open the application on:
http://<server-host>:8001/
For a real server deployment, avoid starting Gunicorn manually in an SSH session. Prefer one of these:
systemdsupervisor- a container runtime
This ensures the service restarts automatically and logs are managed properly.
In a typical production setup:
- Gunicorn listens on an internal port such as
8001 - Nginx or Apache listens on
80or443 - the reverse proxy forwards requests to Gunicorn
This is the preferred setup if the application is exposed publicly.
Run the Flask app directly:
python3 backend.pyThen open:
http://localhost:5000/
Note: you do not need a separate python -m http.server. Flask already serves
the HTML template and static assets for this project.
GET /: renders the main interfacePOST /run: accepts uploaded files and selected schedulers, runsosp, and returns JSON results
The /run endpoint expects:
inputDag: DAG fileinputMachine: machine description filescheduler[]: one or more scheduler namestimeLimit: optional time limit in seconds
Current backend limits in code:
- maximum upload size per file: 50 MB
- maximum scheduling time accepted by the backend: 600 seconds
- default scheduling time if omitted: 60 seconds
Even if Gunicorn allows a much longer request timeout, the application itself currently clamps the scheduler runtime to at most 600 seconds.
Supported DAG formats in the UI:
.mtx.dot.hdag
Machine file format references are linked directly from the application UI.
If scheduling fails immediately, check that the executable exists:
ls -l third_party/OneStopParallel/build/apps/ospIf it is missing, initialize the submodule and rebuild OneStopParallel.
Make sure the executable has the proper permissions:
chmod +x third_party/OneStopParallel/build/apps/ospThere are two time-related controls:
- Gunicorn timeout
- application-level
timeLimithandling inbackend.py
If a user enters a larger value, the backend still caps runtime at 600 seconds.
If the web page loads but /run fails, the most common causes on a server are:
- the
ospexecutable was not built - the service user does not have permission to execute
osp - required input paths or working directories are not writable
- the app was started from the wrong repository directory
Make sure Gunicorn is launched from the project root so backend.py resolves:
backend:app- The frontend scheduler list and recommendation wizard are driven by
static/schedulers.json. - The backend returns generated schedule files as base64 and the browser converts them back into downloadable text files.
- Each request runs in its own temporary directory, so uploaded files are not stored permanently by the app.
This repository is licensed under the Apache License 2.0.
If you redistribute or deploy this project, also review the license terms of the upstream OneStopParallel dependency and any other bundled third-party components.