Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
1c5adad
Add option for the short-term simulation to record event executions i…
david-chapela Feb 26, 2025
9b54044
Functions to transform event log into token-movement-events for front…
david-chapela Feb 26, 2025
de4bbe9
Functions to compute initial BPS state and run short-term simulation,…
david-chapela Feb 26, 2025
f0e59c0
Main pipeline for both interactions from front-end webapp
david-chapela Feb 26, 2025
6465c30
Files for testing main pipeline
david-chapela Feb 26, 2025
e7d4204
Refactor to adapt current Prosimos "bugs"
david-chapela Feb 26, 2025
c41bbf0
Refactor to adapt to Prosimos fixes
david-chapela Feb 27, 2025
65e2ec0
Create a microservice for Python scripts: Initial FastAPI setup
Mar 6, 2025
d62c30c
Create a microservice for Python scripts: Start simulation request
Mar 7, 2025
43b4661
Create a microservice for Python scripts: Resume simulation request
Mar 13, 2025
e02a0d1
Fix simulated log post-processing
david-chapela Apr 6, 2025
582e910
Refactor: repair the tokenIDs to match pre-computed events
david-chapela Apr 6, 2025
430883c
Add advancement of token before START an event
david-chapela Apr 6, 2025
ba44787
Fix filtering error when computing token movements, consider also eve…
david-chapela Apr 6, 2025
d2e6050
Fix frame token ID repair when the previous events do not contain the…
david-chapela Apr 7, 2025
69e9151
Python microservice should not read events from file but from DB
May 7, 2025
de02963
Assign token IDs to SORTED list of elements
david-chapela May 13, 2025
85b582e
N-Grams: Migration
May 19, 2025
5c3f730
N-Grams: Save n-grams
May 19, 2025
712c92e
N-Grams: Read n-gram
May 19, 2025
bde595d
N-Grams: replaced loading the entire dictionary into the memory by re…
Jun 8, 2025
807a7e1
N-Grams: added the default marking
Jun 9, 2025
73a30b3
requirements version
TalehTaghi Nov 7, 2025
d88f9f4
DB migrations fixed
TalehTaghi Nov 10, 2025
d4eed46
Installing Prosimos locally
TalehTaghi Nov 27, 2025
e149d32
Cron for wiping old data out: Endpoint for deleting n-grams
TalehTaghi Mar 23, 2026
1caf7ba
End time fix (tag: unsure)
TalehTaghi Apr 4, 2026
2dad32d
Add Docker runtime and VPS migration workflow
TalehTaghi Apr 4, 2026
2163f71
Merge pull request #3 from AutomatedProcessImprovement/docker-deployment
TalehTaghi Apr 4, 2026
3f2252f
Add branch auto-deploy workflow for VPS
TalehTaghi Apr 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# VCS
.git
.gitignore

# Python cache and virtualenvs
__pycache__/
*.py[cod]
*.pyo
*.pyd
*.so
*.egg-info/
.venv/
venv/

# Local artifacts / logs
*.log
output.json
simulation_warnings.txt
debug_after_input_handler.csv

# Runtime/generated process data
processes/
process-1/

# Large offline evaluation assets not needed in API container
test/

# Notebook and editor artifacts
.ipynb_checkpoints/
.idea/
.vscode/

# Keep Docker context focused on source and config
samples/
5 changes: 5 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
DB_HOST=localhost
DB_PORT=3306
DB_USER=your_username
DB_PASSWORD=your_password
DB_NAME=your_db
61 changes: 61 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: Deploy to VPS

on:
push:
branches:
- web-application-version
workflow_dispatch:

concurrency:
group: deploy-web-application-version
cancel-in-progress: false

jobs:
deploy:
runs-on: ubuntu-latest
environment: production

steps:
- name: Deploy over SSH
uses: appleboy/ssh-action@v1.2.0
env:
DEPLOY_BRANCH: web-application-version
DEPLOY_PATH: ${{ vars.DEPLOY_PATH }}
IMAGE_NAME: ${{ vars.IMAGE_NAME }}
CONTAINER_NAME: ${{ vars.CONTAINER_NAME }}
APP_PORT: ${{ vars.APP_PORT }}
with:
host: ${{ secrets.VPS_HOST }}
username: ${{ secrets.VPS_USER }}
key: ${{ secrets.VPS_SSH_KEY }}
port: ${{ secrets.VPS_PORT }}
script_stop: true
envs: DEPLOY_BRANCH,DEPLOY_PATH,IMAGE_NAME,CONTAINER_NAME,APP_PORT
script: |
set -euo pipefail

cd "$DEPLOY_PATH"
git fetch origin "$DEPLOY_BRANCH"
git checkout "$DEPLOY_BRANCH"
git reset --hard "origin/$DEPLOY_BRANCH"

docker build -t "$IMAGE_NAME" .

docker rm -f "${CONTAINER_NAME}_migrate" >/dev/null 2>&1 || true

docker run --rm \
--name "${CONTAINER_NAME}_migrate" \
--env-file ~/app/.env \
-e RUN_MIGRATIONS=1 \
"$IMAGE_NAME" true

docker rm -f "$CONTAINER_NAME" >/dev/null 2>&1 || true

docker run -d \
--name "$CONTAINER_NAME" \
--restart unless-stopped \
--env-file ~/app/.env \
-p "$APP_PORT:8000" \
"$IMAGE_NAME"

docker image prune -f
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -135,5 +135,8 @@ dmypy.json
.idea/
poetry.lock
.DS_Store
/processes

output.json
output.json
/None
/simulation_warnings.txt
37 changes: 37 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
FROM python:3.11-slim

ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
PIP_NO_CACHE_DIR=1

WORKDIR /app

# Build deps are needed for packages such as lxml/scipy when wheels are unavailable.
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
build-essential \
gcc \
g++ \
libffi-dev \
libxml2-dev \
libxslt1-dev \
&& rm -rf /var/lib/apt/lists/*

COPY requirements.txt /tmp/requirements.txt

# requirements.txt references a local editable Prosimos path (-e ../prosimos).
# For container builds, install the rest and then install Prosimos from a pip spec.
ARG PROSIMOS_PIP_SPEC="prosimos==2.0.6"
RUN grep -v "^-e ../prosimos" /tmp/requirements.txt > /tmp/requirements.docker.txt \
&& pip install --upgrade pip \
&& pip install -r /tmp/requirements.docker.txt \
&& pip install "${PROSIMOS_PIP_SPEC}"

COPY . /app
COPY docker/entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh

EXPOSE 8000

ENTRYPOINT ["/entrypoint.sh"]
CMD ["uvicorn", "main_web_app:app", "--host", "0.0.0.0", "--port", "8000"]
95 changes: 91 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,6 @@ You can also use dataset groups:

To run the evaluation:

### Running

To run the evaluation:

```
python test/evaluate_with_existing_alog.py DATASET_NAME --runs 10 --cut-strategy fixed
```
Expand Down Expand Up @@ -88,3 +84,94 @@ Results are saved in the `outputs/<DATASET>/<run_id>` directory, including:
- Cut strategy
- Per cut-off aggregated metrics
- Overall averages and comparisons between flavours

---

## Docker on VPS (without docker-compose)

This repository includes a `Dockerfile` and `docker/entrypoint.sh`.
Use a managed/external MySQL instance on your VPS and run migrations explicitly before app startup.

### 1) Build image

```bash
docker build -t ongoing-bps-state:local .
```

### 2) Run DB migrations (one-off)

Set DB variables so Alembic can connect:

- `DB_USER`
- `DB_PASSWORD`
- `DB_HOST`
- `DB_PORT`
- `DB_NAME`

Then run:

```bash
docker run --rm \
-e DB_USER=<user> \
-e DB_PASSWORD=<password> \
-e DB_HOST=<host> \
-e DB_PORT=3306 \
-e DB_NAME=<database> \
ongoing-bps-state:local \
alembic upgrade head
```

### 3) Start API container

```bash
docker run -d --name ongoing-bps-state \
-p 8000:8000 \
-e DB_USER=<user> \
-e DB_PASSWORD=<password> \
-e DB_HOST=<host> \
-e DB_PORT=3306 \
-e DB_NAME=<database> \
ongoing-bps-state:local
```

App endpoint:

- `http://<your-vps-ip>:8000/docs`

### Optional: run migrations automatically on container start

`docker/entrypoint.sh` supports `RUN_MIGRATIONS=1` and waits for DB reachability before `alembic upgrade head`.
When `RUN_MIGRATIONS=1`, set at least `DB_USER`, `DB_PASSWORD`, and `DB_NAME` (and usually `DB_HOST`/`DB_PORT`).
For production, prefer explicit one-off migrations during deploys to avoid concurrent migration runners.

---

### GitHub auto-deploy to VPS

A workflow is available at `.github/workflows/deploy.yml`.
It deploys automatically on every push to `web-application-version` (including merges into that branch), and can also be started manually from Actions (`workflow_dispatch`).

Required GitHub **Secrets**:

- `VPS_HOST`
- `VPS_PORT`
- `VPS_USER`
- `VPS_SSH_KEY` (private key content)

Required GitHub **Variables**:

- `DEPLOY_PATH` (absolute path of repo on VPS, e.g. `/opt/ongoing-bps-state`)
- `IMAGE_NAME` (e.g. `ongoing-bps-state:prod`)
- `CONTAINER_NAME` (e.g. `ongoing-bps-state`)
- `APP_PORT` (e.g. `8000`)

What the pipeline does on VPS:

1. Pulls the latest code of `web-application-version`.
2. Builds the Docker image.
3. Runs migrations by starting a short-lived container with `RUN_MIGRATIONS=1`.
4. Replaces the running app container with the new image.

VPS requirement:

- `~/app/.env` must exist on the server and include DB settings (`DB_USER`, `DB_PASSWORD`, `DB_HOST`, `DB_PORT`, `DB_NAME`).
119 changes: 119 additions & 0 deletions alembic.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# A generic, single database configuration.

[alembic]
# path to migration scripts
# Use forward slashes (/) also on windows to provide an os agnostic path
script_location = alembic

# template used to generate migration file names; The default value is %%(rev)s_%%(slug)s
# Uncomment the line below if you want the files to be prepended with date and time
# see https://alembic.sqlalchemy.org/en/latest/tutorial.html#editing-the-ini-file
# for all available tokens
# file_template = %%(year)d_%%(month).2d_%%(day).2d_%%(hour).2d%%(minute).2d-%%(rev)s_%%(slug)s

# sys.path path, will be prepended to sys.path if present.
# defaults to the current working directory.
prepend_sys_path = .

# timezone to use when rendering the date within the migration file
# as well as the filename.
# If specified, requires the python>=3.9 or backports.zoneinfo library and tzdata library.
# Any required deps can installed by adding `alembic[tz]` to the pip requirements
# string value is passed to ZoneInfo()
# leave blank for localtime
# timezone =

# max length of characters to apply to the "slug" field
# truncate_slug_length = 40

# set to 'true' to run the environment during
# the 'revision' command, regardless of autogenerate
# revision_environment = false

# set to 'true' to allow .pyc and .pyo files without
# a source .py file to be detected as revisions in the
# versions/ directory
# sourceless = false

# version location specification; This defaults
# to alembic/versions. When using multiple version
# directories, initial revisions must be specified with --version-path.
# The path separator used here should be the separator specified by "version_path_separator" below.
# version_locations = %(here)s/bar:%(here)s/bat:alembic/versions

# version path separator; As mentioned above, this is the character used to split
# version_locations. The default within new alembic.ini files is "os", which uses os.pathsep.
# If this key is omitted entirely, it falls back to the legacy behavior of splitting on spaces and/or commas.
# Valid values for version_path_separator are:
#
# version_path_separator = :
# version_path_separator = ;
# version_path_separator = space
# version_path_separator = newline
#
# Use os.pathsep. Default configuration used for new projects.
version_path_separator = os

# set to 'true' to search source files recursively
# in each "version_locations" directory
# new in Alembic version 1.10
# recursive_version_locations = false

# the output encoding used when revision files
# are written from script.py.mako
# output_encoding = utf-8

# sqlalchemy.url = driver://user:pass@localhost/dbname


[post_write_hooks]
# post_write_hooks defines scripts or Python functions that are run
# on newly generated revision scripts. See the documentation for further
# detail and examples

# format using "black" - use the console_scripts runner, against the "black" entrypoint
# hooks = black
# black.type = console_scripts
# black.entrypoint = black
# black.options = -l 79 REVISION_SCRIPT_FILENAME

# lint with attempts to fix using "ruff" - use the exec runner, execute a binary
# hooks = ruff
# ruff.type = exec
# ruff.executable = %(here)s/.venv/bin/ruff
# ruff.options = check --fix REVISION_SCRIPT_FILENAME

# Logging configuration
[loggers]
keys = root,sqlalchemy,alembic

[handlers]
keys = console

[formatters]
keys = generic

[logger_root]
level = WARNING
handlers = console
qualname =

[logger_sqlalchemy]
level = WARNING
handlers =
qualname = sqlalchemy.engine

[logger_alembic]
level = INFO
handlers =
qualname = alembic

[handler_console]
class = StreamHandler
args = (sys.stderr,)
level = NOTSET
formatter = generic

[formatter_generic]
format = %(levelname)-5.5s [%(name)s] %(message)s
datefmt = %H:%M:%S
1 change: 1 addition & 0 deletions alembic/README
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Generic single-database configuration.
Loading
Loading