graphmdo 0.2.0__tar.gz → 2.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- graphmdo-2.0.0/.github/workflows/latest-dependencies.yml +26 -0
- graphmdo-2.0.0/.github/workflows/quality.yml +100 -0
- graphmdo-2.0.0/.github/workflows/security.yml +55 -0
- {graphmdo-0.2.0 → graphmdo-2.0.0}/.gitignore +7 -2
- graphmdo-2.0.0/AGENTS.md +105 -0
- graphmdo-2.0.0/Dockerfile +56 -0
- graphmdo-2.0.0/LICENSE +373 -0
- graphmdo-2.0.0/PKG-INFO +263 -0
- graphmdo-2.0.0/README.md +239 -0
- graphmdo-2.0.0/docker-compose.yml +70 -0
- graphmdo-2.0.0/docs/api/core/errors.md +3 -0
- graphmdo-2.0.0/docs/api/core/mda.md +3 -0
- graphmdo-2.0.0/docs/api/optimization/bo_library.md +28 -0
- graphmdo-2.0.0/docs/api/optimization/optimizer.md +24 -0
- graphmdo-2.0.0/docs/api/schema.md +5 -0
- graphmdo-2.0.0/docs/api/validation.md +7 -0
- {graphmdo-0.2.0 → graphmdo-2.0.0}/docs/dev-guide/contributing.md +7 -2
- graphmdo-2.0.0/docs/dev-guide/releasing.md +34 -0
- {graphmdo-0.2.0 → graphmdo-2.0.0}/docs/index.md +3 -3
- graphmdo-2.0.0/docs/technical-reference/architecture.md +96 -0
- graphmdo-2.0.0/docs/technical-reference/microservices.md +47 -0
- graphmdo-2.0.0/docs/technical-reference/study-schema.json +394 -0
- graphmdo-2.0.0/docs/technical-reference/study-schema.md +316 -0
- {graphmdo-0.2.0 → graphmdo-2.0.0}/docs/user-guide/installation.md +4 -2
- graphmdo-2.0.0/docs/user-guide/quick-start.md +127 -0
- graphmdo-2.0.0/docs/user-guide/running-optimization.md +151 -0
- {graphmdo-0.2.0 → graphmdo-2.0.0}/main.py +24 -17
- {graphmdo-0.2.0 → graphmdo-2.0.0}/mkdocs.yml +9 -1
- {graphmdo-0.2.0 → graphmdo-2.0.0}/pyproject.toml +15 -13
- graphmdo-2.0.0/src/mdo_framework/__init__.py +5 -0
- graphmdo-2.0.0/src/mdo_framework/core/__init__.py +5 -0
- graphmdo-2.0.0/src/mdo_framework/core/components.py +206 -0
- graphmdo-2.0.0/src/mdo_framework/core/components.py,cover +77 -0
- graphmdo-2.0.0/src/mdo_framework/core/dependencies.py +130 -0
- graphmdo-2.0.0/src/mdo_framework/core/errors.py +124 -0
- graphmdo-2.0.0/src/mdo_framework/core/evaluators.py +56 -0
- graphmdo-2.0.0/src/mdo_framework/core/evaluators.py,cover +42 -0
- graphmdo-2.0.0/src/mdo_framework/core/mda.py +166 -0
- {graphmdo-0.2.0 → graphmdo-2.0.0}/src/mdo_framework/core/surrogates.py +6 -0
- graphmdo-2.0.0/src/mdo_framework/core/surrogates.py,cover +72 -0
- graphmdo-2.0.0/src/mdo_framework/core/topology.py +143 -0
- graphmdo-2.0.0/src/mdo_framework/core/topology.py,cover +105 -0
- graphmdo-2.0.0/src/mdo_framework/core/translator.py +149 -0
- graphmdo-2.0.0/src/mdo_framework/core/translator.py,cover +70 -0
- graphmdo-2.0.0/src/mdo_framework/db/__init__.py +5 -0
- {graphmdo-0.2.0 → graphmdo-2.0.0}/src/mdo_framework/db/client.py +6 -0
- graphmdo-2.0.0/src/mdo_framework/db/client.py,cover +38 -0
- graphmdo-2.0.0/src/mdo_framework/db/graph_manager.py +550 -0
- graphmdo-2.0.0/src/mdo_framework/db/graph_manager.py,cover +240 -0
- graphmdo-2.0.0/src/mdo_framework/optimization/__init__.py +5 -0
- graphmdo-2.0.0/src/mdo_framework/optimization/ax_algo_lib.py +298 -0
- graphmdo-2.0.0/src/mdo_framework/optimization/ax_algo_lib.py,cover +216 -0
- graphmdo-2.0.0/src/mdo_framework/optimization/bo_library.py +440 -0
- graphmdo-2.0.0/src/mdo_framework/optimization/bo_types.py +646 -0
- graphmdo-2.0.0/src/mdo_framework/optimization/errors.py +33 -0
- graphmdo-2.0.0/src/mdo_framework/optimization/optimizer.py +603 -0
- graphmdo-2.0.0/src/mdo_framework/optimization/optimizer.py,cover +266 -0
- graphmdo-2.0.0/src/mdo_framework/optimization/parameter_codec.py +141 -0
- graphmdo-2.0.0/src/mdo_framework/optimization/random_search.py +130 -0
- graphmdo-2.0.0/src/mdo_framework/schema.py +569 -0
- graphmdo-2.0.0/src/mdo_framework/validation.py +711 -0
- graphmdo-2.0.0/src/services/__init__.py +5 -0
- graphmdo-2.0.0/src/services/errors.py +39 -0
- graphmdo-2.0.0/src/services/execution/__init__.py +5 -0
- {graphmdo-0.2.0 → graphmdo-2.0.0}/src/services/execution/main.py +65 -48
- graphmdo-2.0.0/src/services/execution/main.py,cover +428 -0
- graphmdo-2.0.0/src/services/graph/__init__.py +5 -0
- graphmdo-2.0.0/src/services/graph/main.py +205 -0
- graphmdo-2.0.0/src/services/graph/main.py,cover +115 -0
- graphmdo-2.0.0/src/services/optimization/__init__.py +5 -0
- graphmdo-2.0.0/src/services/optimization/main.py +246 -0
- graphmdo-2.0.0/src/services/optimization/main.py,cover +165 -0
- {graphmdo-0.2.0 → graphmdo-2.0.0}/tests/conftest.py +26 -3
- graphmdo-2.0.0/tests/e2e/conftest.py +174 -0
- graphmdo-2.0.0/tests/e2e/test_budget.py +128 -0
- graphmdo-2.0.0/tests/e2e/test_choices.py +142 -0
- graphmdo-2.0.0/tests/e2e/test_failures.py +129 -0
- graphmdo-2.0.0/tests/e2e/test_graph.py +155 -0
- graphmdo-2.0.0/tests/e2e/test_objectives.py +107 -0
- graphmdo-2.0.0/tests/e2e/test_reproducibility.py +32 -0
- graphmdo-2.0.0/tests/e2e/test_service.py +213 -0
- graphmdo-2.0.0/tests/fakes/__init__.py +5 -0
- graphmdo-2.0.0/tests/fakes/falkordb.py +279 -0
- graphmdo-2.0.0/tests/smoke/compose_walkthrough.py +63 -0
- graphmdo-2.0.0/tests/smoke/test_installed_wheel.py +49 -0
- graphmdo-2.0.0/tests/test_ax_algo_lib.py +509 -0
- graphmdo-2.0.0/tests/test_bo_library.py +940 -0
- graphmdo-2.0.0/tests/test_bo_types.py +692 -0
- graphmdo-2.0.0/tests/test_components.py +541 -0
- {graphmdo-0.2.0 → graphmdo-2.0.0}/tests/test_db_client.py +6 -0
- graphmdo-2.0.0/tests/test_dependencies.py +267 -0
- graphmdo-2.0.0/tests/test_deployment.py +89 -0
- graphmdo-2.0.0/tests/test_docs_schema.py +34 -0
- graphmdo-2.0.0/tests/test_errors.py +116 -0
- graphmdo-2.0.0/tests/test_graph_manager.py +813 -0
- graphmdo-2.0.0/tests/test_main.py +60 -0
- graphmdo-2.0.0/tests/test_mda.py +576 -0
- graphmdo-2.0.0/tests/test_optimization_errors.py +31 -0
- graphmdo-2.0.0/tests/test_optimizer.py +954 -0
- graphmdo-2.0.0/tests/test_parameter_codec.py +140 -0
- graphmdo-2.0.0/tests/test_schema.py +884 -0
- graphmdo-2.0.0/tests/test_services.py +2168 -0
- {graphmdo-0.2.0 → graphmdo-2.0.0}/tests/test_services_opt.py +6 -0
- {graphmdo-0.2.0 → graphmdo-2.0.0}/tests/test_surrogates.py +6 -0
- graphmdo-2.0.0/tests/test_tool_values.py +138 -0
- graphmdo-2.0.0/tests/test_topology.py +262 -0
- graphmdo-2.0.0/tests/test_translator.py +526 -0
- graphmdo-2.0.0/tests/test_validation.py +1115 -0
- {graphmdo-0.2.0 → graphmdo-2.0.0}/uv.lock +802 -577
- graphmdo-0.2.0/.github/workflows/quality.yml +0 -29
- graphmdo-0.2.0/.github/workflows/security.yml +0 -44
- graphmdo-0.2.0/AGENTS.md +0 -38
- graphmdo-0.2.0/Dockerfile +0 -35
- graphmdo-0.2.0/LICENSE +0 -21
- graphmdo-0.2.0/PKG-INFO +0 -143
- graphmdo-0.2.0/README.md +0 -122
- graphmdo-0.2.0/docker-compose.yml +0 -41
- graphmdo-0.2.0/docs/api/optimization/optimizer.md +0 -15
- graphmdo-0.2.0/docs/technical-reference/architecture.md +0 -45
- graphmdo-0.2.0/docs/technical-reference/microservices.md +0 -24
- graphmdo-0.2.0/docs/user-guide/quick-start.md +0 -89
- graphmdo-0.2.0/docs/user-guide/running-optimization.md +0 -58
- graphmdo-0.2.0/src/mdo_framework/__init__.py +0 -0
- graphmdo-0.2.0/src/mdo_framework/core/__init__.py +0 -0
- graphmdo-0.2.0/src/mdo_framework/core/components.py +0 -85
- graphmdo-0.2.0/src/mdo_framework/core/evaluators.py +0 -33
- graphmdo-0.2.0/src/mdo_framework/core/topology.py +0 -99
- graphmdo-0.2.0/src/mdo_framework/core/translator.py +0 -80
- graphmdo-0.2.0/src/mdo_framework/db/__init__.py +0 -0
- graphmdo-0.2.0/src/mdo_framework/db/graph_manager.py +0 -226
- graphmdo-0.2.0/src/mdo_framework/optimization/__init__.py +0 -0
- graphmdo-0.2.0/src/mdo_framework/optimization/optimizer.py +0 -274
- graphmdo-0.2.0/src/services/__init__.py +0 -0
- graphmdo-0.2.0/src/services/execution/__init__.py +0 -0
- graphmdo-0.2.0/src/services/graph/__init__.py +0 -0
- graphmdo-0.2.0/src/services/graph/main.py +0 -109
- graphmdo-0.2.0/src/services/optimization/__init__.py +0 -0
- graphmdo-0.2.0/src/services/optimization/main.py +0 -159
- graphmdo-0.2.0/tests/test_components.py +0 -171
- graphmdo-0.2.0/tests/test_graph_manager.py +0 -199
- graphmdo-0.2.0/tests/test_integration.py +0 -64
- graphmdo-0.2.0/tests/test_main.py +0 -47
- graphmdo-0.2.0/tests/test_optimizer.py +0 -209
- graphmdo-0.2.0/tests/test_services.py +0 -969
- graphmdo-0.2.0/tests/test_topology.py +0 -70
- graphmdo-0.2.0/tests/test_translator.py +0 -88
- {graphmdo-0.2.0 → graphmdo-2.0.0}/.github/workflows/docs.yml +0 -0
- {graphmdo-0.2.0 → graphmdo-2.0.0}/.github/workflows/pypi-publish.yml +0 -0
- {graphmdo-0.2.0 → graphmdo-2.0.0}/.pre-commit-config.yaml +0 -0
- {graphmdo-0.2.0 → graphmdo-2.0.0}/.python-version +0 -0
- {graphmdo-0.2.0 → graphmdo-2.0.0}/docs/api/core/components.md +0 -0
- {graphmdo-0.2.0 → graphmdo-2.0.0}/docs/api/core/surrogates.md +0 -0
- {graphmdo-0.2.0 → graphmdo-2.0.0}/docs/api/core/translator.md +0 -0
- {graphmdo-0.2.0 → graphmdo-2.0.0}/docs/api/db/client.md +0 -0
- {graphmdo-0.2.0 → graphmdo-2.0.0}/docs/api/db/graph_manager.md +0 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
name: Latest Allowed Dependencies
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
schedule:
|
|
5
|
+
- cron: "0 5 * * 0"
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
test-latest:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v4
|
|
13
|
+
- name: Install uv
|
|
14
|
+
uses: astral-sh/setup-uv@v5
|
|
15
|
+
- name: Set up Python
|
|
16
|
+
uses: actions/setup-python@v5
|
|
17
|
+
with:
|
|
18
|
+
python-version: "3.12"
|
|
19
|
+
- name: Upgrade dependency resolution
|
|
20
|
+
run: uv lock --upgrade
|
|
21
|
+
- name: Install upgraded dependencies
|
|
22
|
+
run: uv sync --all-extras --dev
|
|
23
|
+
- name: Run test suite
|
|
24
|
+
env:
|
|
25
|
+
PYTHONPATH: .
|
|
26
|
+
run: uv run pytest tests/
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
name: Quality Checks
|
|
2
|
+
|
|
3
|
+
on: [push, pull_request]
|
|
4
|
+
|
|
5
|
+
jobs:
|
|
6
|
+
quality:
|
|
7
|
+
runs-on: ubuntu-latest
|
|
8
|
+
steps:
|
|
9
|
+
- uses: actions/checkout@v4
|
|
10
|
+
- name: Install uv
|
|
11
|
+
uses: astral-sh/setup-uv@v5
|
|
12
|
+
- name: Set up Python
|
|
13
|
+
uses: actions/setup-python@v5
|
|
14
|
+
with:
|
|
15
|
+
python-version: "3.12"
|
|
16
|
+
- name: Install dependencies
|
|
17
|
+
run: uv sync --frozen --all-extras --dev
|
|
18
|
+
- name: Run Ruff
|
|
19
|
+
run: uv run ruff check .
|
|
20
|
+
- name: Run Tests
|
|
21
|
+
env:
|
|
22
|
+
PYTHONPATH: .
|
|
23
|
+
run: uv run pytest -m "not e2e" --cov=src/mdo_framework --cov=src/services --cov-report=xml tests/
|
|
24
|
+
- name: Upload coverage to Codecov
|
|
25
|
+
uses: codecov/codecov-action@v5
|
|
26
|
+
with:
|
|
27
|
+
token: ${{ secrets.CODECOV_TOKEN }}
|
|
28
|
+
files: ./coverage.xml
|
|
29
|
+
flags: unit
|
|
30
|
+
fail_ci_if_error: false
|
|
31
|
+
|
|
32
|
+
e2e:
|
|
33
|
+
name: End-to-end regression suite (real Ax + GEMSEO)
|
|
34
|
+
runs-on: ubuntu-latest
|
|
35
|
+
timeout-minutes: 15
|
|
36
|
+
steps:
|
|
37
|
+
- uses: actions/checkout@v4
|
|
38
|
+
- name: Install uv
|
|
39
|
+
uses: astral-sh/setup-uv@v5
|
|
40
|
+
- name: Set up Python
|
|
41
|
+
uses: actions/setup-python@v5
|
|
42
|
+
with:
|
|
43
|
+
python-version: "3.12"
|
|
44
|
+
- name: Install dependencies
|
|
45
|
+
run: uv sync --frozen --all-extras --dev
|
|
46
|
+
- name: Run end-to-end tests
|
|
47
|
+
env:
|
|
48
|
+
OMP_NUM_THREADS: "1"
|
|
49
|
+
PYTHONPATH: .
|
|
50
|
+
run: uv run pytest -m e2e --durations=10 --cov=src/mdo_framework --cov=src/services --cov-report=xml tests/
|
|
51
|
+
- name: Upload coverage to Codecov
|
|
52
|
+
uses: codecov/codecov-action@v5
|
|
53
|
+
with:
|
|
54
|
+
token: ${{ secrets.CODECOV_TOKEN }}
|
|
55
|
+
files: ./coverage.xml
|
|
56
|
+
flags: e2e
|
|
57
|
+
fail_ci_if_error: false
|
|
58
|
+
|
|
59
|
+
wheel-smoke:
|
|
60
|
+
name: Installed wheel optimization smoke test
|
|
61
|
+
runs-on: ubuntu-latest
|
|
62
|
+
steps:
|
|
63
|
+
- uses: actions/checkout@v4
|
|
64
|
+
- name: Install uv
|
|
65
|
+
uses: astral-sh/setup-uv@v5
|
|
66
|
+
- name: Set up Python
|
|
67
|
+
uses: actions/setup-python@v5
|
|
68
|
+
with:
|
|
69
|
+
python-version: "3.12"
|
|
70
|
+
- name: Build wheel
|
|
71
|
+
run: uv build
|
|
72
|
+
- name: Create clean environment
|
|
73
|
+
run: uv venv --python 3.12 .venv-wheel-smoke
|
|
74
|
+
- name: Install wheel and test runner without lockfile
|
|
75
|
+
run: uv pip install --python .venv-wheel-smoke dist/*.whl pytest
|
|
76
|
+
- name: Run installed-wheel smoke test
|
|
77
|
+
run: .venv-wheel-smoke/bin/python -m pytest tests/smoke/test_installed_wheel.py -q
|
|
78
|
+
|
|
79
|
+
compose-smoke:
|
|
80
|
+
name: Docker Compose walkthrough smoke test
|
|
81
|
+
runs-on: ubuntu-latest
|
|
82
|
+
steps:
|
|
83
|
+
- uses: actions/checkout@v4
|
|
84
|
+
- name: Start the stack and wait for healthy services
|
|
85
|
+
run: docker compose up -d --build --wait --wait-timeout 300
|
|
86
|
+
- name: Image has no dev dependencies
|
|
87
|
+
run: |
|
|
88
|
+
if docker compose exec -T graph-service python -c "import pytest"; then
|
|
89
|
+
echo "pytest must not be installed in the runtime image"; exit 1
|
|
90
|
+
fi
|
|
91
|
+
- name: Install uv
|
|
92
|
+
uses: astral-sh/setup-uv@v5
|
|
93
|
+
- name: Replay the documented walkthrough
|
|
94
|
+
run: uv run --no-project --python 3.12 --with httpx python tests/smoke/compose_walkthrough.py
|
|
95
|
+
- name: Service logs
|
|
96
|
+
if: failure()
|
|
97
|
+
run: docker compose logs
|
|
98
|
+
- name: Tear down
|
|
99
|
+
if: always()
|
|
100
|
+
run: docker compose down -v
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
name: Security Scan
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ "main" ]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [ "main" ]
|
|
8
|
+
|
|
9
|
+
env:
|
|
10
|
+
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
build:
|
|
14
|
+
name: Build
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
permissions:
|
|
17
|
+
contents: read
|
|
18
|
+
security-events: write
|
|
19
|
+
steps:
|
|
20
|
+
- name: Free Disk Space (Ubuntu)
|
|
21
|
+
uses: jlumbroso/free-disk-space@main
|
|
22
|
+
with:
|
|
23
|
+
tool-cache: false
|
|
24
|
+
android: true
|
|
25
|
+
dotnet: true
|
|
26
|
+
haskell: true
|
|
27
|
+
large-packages: true
|
|
28
|
+
docker-images: true
|
|
29
|
+
swap-storage: true
|
|
30
|
+
|
|
31
|
+
- name: Setup Docker
|
|
32
|
+
uses: docker/setup-buildx-action@v3
|
|
33
|
+
|
|
34
|
+
- name: Checkout code
|
|
35
|
+
uses: actions/checkout@v4
|
|
36
|
+
|
|
37
|
+
- name: Build an image from Dockerfile
|
|
38
|
+
run: |
|
|
39
|
+
docker build -t docker.io/my-organization/my-app:${{ github.sha }} .
|
|
40
|
+
|
|
41
|
+
- name: Scan image for vulnerabilities
|
|
42
|
+
uses: anchore/scan-action@v7.4.2
|
|
43
|
+
id: scan
|
|
44
|
+
with:
|
|
45
|
+
image: 'docker.io/my-organization/my-app:${{ github.sha }}'
|
|
46
|
+
fail-build: true
|
|
47
|
+
severity-cutoff: high
|
|
48
|
+
output-format: sarif
|
|
49
|
+
only-fixed: true
|
|
50
|
+
|
|
51
|
+
- name: Upload vulnerability report
|
|
52
|
+
uses: github/codeql-action/upload-sarif@v4
|
|
53
|
+
if: always() && steps.scan.outputs.sarif != ''
|
|
54
|
+
with:
|
|
55
|
+
sarif_file: ${{ steps.scan.outputs.sarif }}
|
|
@@ -201,12 +201,17 @@ cython_debug/
|
|
|
201
201
|
.cursorignore
|
|
202
202
|
.cursorindexingignore
|
|
203
203
|
|
|
204
|
+
# VS Code settings
|
|
205
|
+
.vscode/
|
|
206
|
+
.agents/
|
|
207
|
+
|
|
204
208
|
# Marimo
|
|
205
209
|
marimo/_static/
|
|
206
210
|
marimo/_lsp/
|
|
207
211
|
__marimo__/
|
|
208
212
|
|
|
209
|
-
#
|
|
213
|
+
# GEMSEO Test Artifacts
|
|
210
214
|
pytest*_out/
|
|
211
|
-
*.openmdao_out
|
|
212
215
|
reports/
|
|
216
|
+
xdsm.html
|
|
217
|
+
opt_history*.png
|
graphmdo-2.0.0/AGENTS.md
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
## Strict Coding Standards
|
|
4
|
+
|
|
5
|
+
1. **PEP 20 (The Zen of Python)**
|
|
6
|
+
- Explicit is better than implicit.
|
|
7
|
+
- Simple is better than complex.
|
|
8
|
+
- Readability counts.
|
|
9
|
+
|
|
10
|
+
2. **PEP 8 (Style Guide for Python Code)**
|
|
11
|
+
- Indentation: 4 spaces.
|
|
12
|
+
- Line Length: 88 characters.
|
|
13
|
+
- Naming Conventions:
|
|
14
|
+
- Functions/Variables: `lowercase_with_underscores`
|
|
15
|
+
- Classes: `CapitalizedWords`
|
|
16
|
+
- Constants: `ALL_CAPS_WITH_UNDERSCORES`
|
|
17
|
+
- Imports: Standard library, third-party, local application.
|
|
18
|
+
- Type Hinting: Use explicit Python 3 type hints.
|
|
19
|
+
|
|
20
|
+
3. **Typing and Interfaces**
|
|
21
|
+
- Target Python 3.12+ syntax (`X | None`, `list[str]`, `dict[str, Any]`).
|
|
22
|
+
- Keep FastAPI request/response contracts explicit with Pydantic models.
|
|
23
|
+
- Prefer small, composable functions over hidden side effects.
|
|
24
|
+
|
|
25
|
+
## Current Codebase Overview
|
|
26
|
+
|
|
27
|
+
- `main.py` is the local paraboloid demo wiring `GraphManager` -> `GraphProblemBuilder` -> `LocalEvaluator` -> `BayesianOptimizer`.
|
|
28
|
+
- `src/mdo_framework/schema.py` defines the typed `StudySchema` contract (`RangeVar`, `ChoiceVar`, `FixedParam`, `StateVar`, `ToolNode`, `Finding`, `ValidationReport`, `StudyValidationError`).
|
|
29
|
+
- `src/mdo_framework/validation.py` holds `validate_study()` (preflight against a request) and `validate_registry()` (tool registry and signature checks); `core/dependencies.py` is the shared dependency walk.
|
|
30
|
+
- `src/mdo_framework/db/` contains the FalkorDB integration (`client.py`, `graph_manager.py`).
|
|
31
|
+
- `src/mdo_framework/core/` contains schema-to-GEMSEO translation and execution helpers (`components.py`, `dependencies.py`, `errors.py`, `evaluators.py`, `mda.py`, `surrogates.py`, `topology.py`, `translator.py`).
|
|
32
|
+
- `src/mdo_framework/optimization/` contains the optimizer orchestration (`optimizer.py`), the backend-neutral Bayesian-optimization driver (`bo_library.py`, `bo_types.py`, `errors.py`) and its backends: Ax (`ax_algo_lib.py`) and a seeded random search (`random_search.py`).
|
|
33
|
+
- `src/services/graph/main.py` exposes the typed Graph Service API: `POST/PUT/DELETE` on `/variables` and `/tools`, `/connections/input`, `/connections/output`, `/schema`, `/clear`, `/health`. Conflicts return `409`, unknown nodes `404`, invalid bodies `422`.
|
|
34
|
+
- `src/services/execution/main.py` exposes the Execution Service API: `/evaluate`, `/health`, plus schema caching, a registry check on each loaded schema (`422` `SCHEMA_INVALID`), and pooled problem instances.
|
|
35
|
+
- `src/services/optimization/main.py` exposes the Optimization Service API: `/optimize` (with a `422` validation preflight), `/validate`, `/health`.
|
|
36
|
+
- `src/services/errors.py` registers the shared request-validation handler (`422` without echoing input) on all three services.
|
|
37
|
+
- `tests/` covers the core modules, services, database layer, optimizer, topology, translator, and the top-level demo entry point.
|
|
38
|
+
- `tests/e2e/` holds the seeded, non-mocked Ax + GEMSEO regression suite (marker `e2e`); open bugs are pinned there as strict xfails.
|
|
39
|
+
|
|
40
|
+
## Runtime Architecture
|
|
41
|
+
|
|
42
|
+
1. **Graph Layer**
|
|
43
|
+
- FalkorDB stores variables, tools, and directed data-flow edges.
|
|
44
|
+
- `GraphManager.get_study_schema()` returns the typed `StudySchema`, the canonical boundary exported to the rest of the system.
|
|
45
|
+
|
|
46
|
+
2. **Translation Layer**
|
|
47
|
+
- `GraphProblemBuilder` builds GEMSEO problems from the `StudySchema`: one `ToolComponent` per tool (strict output contract, finite-difference Jacobians) chained in a `StrictMDAChain` (`core/mda.py`).
|
|
48
|
+
- Coupled tools run sequentially (Gauss-Seidel) by default; `MDASettings` selects the algorithm, and a coupled group that does not converge raises `MDANotConvergedError`.
|
|
49
|
+
- `TopologicalAnalyzer` resolves dependencies and extracts optimization parameters from requested outputs.
|
|
50
|
+
|
|
51
|
+
3. **Evaluation Layer**
|
|
52
|
+
- Local execution uses `LocalEvaluator`.
|
|
53
|
+
- Remote execution uses the Execution Service, which maintains a `SchemaProvider` cache and a `ProblemPool` of initialized GEMSEO problems.
|
|
54
|
+
|
|
55
|
+
4. **Optimization Layer**
|
|
56
|
+
- `BayesianOptimizer` builds the GEMSEO scenario and runs a `BaseBOLibrary` backend (`Ax_Bayesian` by default, `BO_RandomSearch`).
|
|
57
|
+
- `BaseBOLibrary` owns the budget (`n_init + n_steps`, plus x0 when evaluated), stopping, failure classification, the guarded start point, user-name metric bindings and constraint feasibility; backends implement only `_setup`, `_ask` and `_tell`.
|
|
58
|
+
|
|
59
|
+
5. **Service Deployment**
|
|
60
|
+
- `docker-compose.yml` runs FalkorDB plus three FastAPI services.
|
|
61
|
+
- Default ports are 8001 (graph), 8002 (execution), and 8003 (optimization).
|
|
62
|
+
|
|
63
|
+
## Implementation Directives
|
|
64
|
+
|
|
65
|
+
- **StudySchema Is the Source of Truth**: Flow data from FalkorDB through `get_study_schema()` into validation, topology analysis, translation, and services. Do not reintroduce untyped dict schemas.
|
|
66
|
+
- **Validate Before Running**: Study-level checks belong in `validate_study()` and tool-registry checks in `validate_registry()`; add new findings there with a stable error code and document them in `docs/technical-reference/study-schema.md`.
|
|
67
|
+
- **Keep the Published JSON Schema in Sync**: After changing `schema.py`, regenerate `docs/technical-reference/study-schema.json` with the command printed by `tests/test_docs_schema.py`.
|
|
68
|
+
- **Preserve Design Variable Order**: Keep FalkorDB insertion order for design variables; do not sort parameter names alphabetically before execution or optimization.
|
|
69
|
+
- **Use Keyword-Based Tool Invocation**: Wrapped tool functions must receive named inputs, not positional fallbacks that can scramble graph-defined ordering.
|
|
70
|
+
- **Raise Typed Evaluation Errors**: A point that cannot be evaluated raises an `EvaluationError` subclass from `core/errors.py` (`ToolExecutionError`, `ToolOutputError`, `MDANotConvergedError`), never a bare exception or a silently returned invalid value; services serialize them with `to_payload()`.
|
|
71
|
+
- **Keep Optimization State Explicit**: The library's `result` (`BORunResult`: trial records, stop reason, best trial, Pareto front) is the authoritative optimization output; avoid hidden cross-object attributes.
|
|
72
|
+
- **Keep Backends Thin**: Stopping, NaN handling, x0, metric naming and feasibility belong in `BaseBOLibrary`; a new backend implements only `_setup`, `_ask` and `_tell` and must pass the shared contract tests.
|
|
73
|
+
- **Respect Constraint Semantics**: Current optimization code uses GEMSEO/Ax convention `g(x) <= 0`; the paraboloid example encodes `c_xy = x - y`.
|
|
74
|
+
- **Extend Service Infrastructure, Do Not Bypass It**: Schema refresh/backoff belongs in `SchemaProvider`; reusable GEMSEO instances belong in `ProblemPool`.
|
|
75
|
+
- **Preserve Service Boundaries**: Cross-service calls should flow through `GRAPH_SERVICE_URL` and `EXECUTION_SERVICE_URL`, matching local and Docker Compose deployment.
|
|
76
|
+
|
|
77
|
+
## Dependency Management
|
|
78
|
+
|
|
79
|
+
- This project uses `uv` for dependency management.
|
|
80
|
+
- Core runtime stack includes FalkorDB, FastAPI, GEMSEO, SMT, Ax Platform, BoTorch, pymoo, httpx, and NumPy/SciPy.
|
|
81
|
+
- Install project dependencies with `uv sync`.
|
|
82
|
+
- Install development dependencies with `uv sync --all-extras --dev`.
|
|
83
|
+
- Add a dependency with `uv add <package_name>`.
|
|
84
|
+
- Run commands in the environment with `uv run <command>`.
|
|
85
|
+
- **Do not use pip install manually.**
|
|
86
|
+
|
|
87
|
+
## Development Commands
|
|
88
|
+
|
|
89
|
+
- Run the local demo: `uv run python main.py`
|
|
90
|
+
- Start the Graph Service: `uv run uvicorn services.graph.main:app --host 0.0.0.0 --port 8001`
|
|
91
|
+
- Start the Execution Service: `uv run uvicorn services.execution.main:app --host 0.0.0.0 --port 8002`
|
|
92
|
+
- Start the Optimization Service: `uv run uvicorn services.optimization.main:app --host 0.0.0.0 --port 8003`
|
|
93
|
+
- Start the full stack with containers: `docker compose up --build`
|
|
94
|
+
|
|
95
|
+
## Validation and Docs
|
|
96
|
+
|
|
97
|
+
- Run all tests with `uv run pytest tests/`.
|
|
98
|
+
- Run fast unit tests with `uv run pytest -m "not e2e" tests/`.
|
|
99
|
+
- Run the real Ax + GEMSEO suite with `OMP_NUM_THREADS=1 uv run pytest -m e2e tests/`.
|
|
100
|
+
- Tests that pin an open bug are `xfail(strict=True)` with the issue number in the
|
|
101
|
+
reason; the PR that fixes the bug removes the marker.
|
|
102
|
+
- Run lint checks with `uv run ruff check .`.
|
|
103
|
+
- Format code with `uv run ruff format .`.
|
|
104
|
+
- Serve documentation locally with `uv run mkdocs serve`.
|
|
105
|
+
- Documentation lives under `docs/` and is built with MkDocs Material.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Stage 1: Build stage
|
|
2
|
+
FROM python:3.12-slim AS builder
|
|
3
|
+
|
|
4
|
+
# Grab uv directly from astral's image
|
|
5
|
+
COPY --from=ghcr.io/astral-sh/uv:latest /uv /bin/
|
|
6
|
+
|
|
7
|
+
# Docker-specific uv optimizations
|
|
8
|
+
ENV UV_COMPILE_BYTECODE=1
|
|
9
|
+
ENV UV_LINK_MODE=copy
|
|
10
|
+
|
|
11
|
+
# Pass a dummy version to setuptools-scm during the docker build to prevent failures
|
|
12
|
+
ENV SETUPTOOLS_SCM_PRETEND_VERSION="0.0.0"
|
|
13
|
+
|
|
14
|
+
WORKDIR /app
|
|
15
|
+
|
|
16
|
+
# Copy dependency files FIRST
|
|
17
|
+
COPY pyproject.toml uv.lock README.md ./
|
|
18
|
+
|
|
19
|
+
# Install dependencies into a virtual environment
|
|
20
|
+
RUN uv sync --frozen --no-dev --no-install-project
|
|
21
|
+
|
|
22
|
+
# Copy your source code
|
|
23
|
+
COPY src/ src/
|
|
24
|
+
|
|
25
|
+
# Install the project itself
|
|
26
|
+
RUN uv sync --frozen --no-dev
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
# Stage 2: Final runtime stage
|
|
30
|
+
FROM python:3.12-slim
|
|
31
|
+
|
|
32
|
+
# Update OS packages to fix vulnerabilities
|
|
33
|
+
RUN apt-get update && apt-get upgrade -y && rm -rf /var/lib/apt/lists/*
|
|
34
|
+
|
|
35
|
+
# Security: Ensure uv/uvx are NOT present in the final image
|
|
36
|
+
RUN rm -f /usr/bin/uv /usr/bin/uvx /bin/uv /bin/uvx
|
|
37
|
+
|
|
38
|
+
WORKDIR /app
|
|
39
|
+
|
|
40
|
+
# Security: Create and use a non-root user
|
|
41
|
+
RUN useradd -m appuser
|
|
42
|
+
RUN chown appuser:appuser /app
|
|
43
|
+
USER appuser
|
|
44
|
+
|
|
45
|
+
# Copy the virtual environment and the source code from the builder stage
|
|
46
|
+
COPY --from=builder --chown=appuser:appuser /app/.venv /app/.venv
|
|
47
|
+
COPY --from=builder --chown=appuser:appuser /app/src /app/src
|
|
48
|
+
|
|
49
|
+
# Set environment variables to use the virtual environment
|
|
50
|
+
ENV PATH="/app/.venv/bin:$PATH"
|
|
51
|
+
|
|
52
|
+
# Graph, execution and optimization services (see docker-compose.yml)
|
|
53
|
+
EXPOSE 8001 8002 8003
|
|
54
|
+
|
|
55
|
+
# Default command
|
|
56
|
+
CMD ["uvicorn", "services.graph.main:app", "--host", "0.0.0.0", "--port", "8001"]
|