feat: initial otko import
Some checks failed
CI / lint (push) Has been cancelled
CI / test (macos-latest, 3.10) (push) Has been cancelled
CI / test (macos-latest, 3.11) (push) Has been cancelled
CI / test (macos-latest, 3.12) (push) Has been cancelled
CI / test (ubuntu-latest, 3.10) (push) Has been cancelled
CI / test (ubuntu-latest, 3.11) (push) Has been cancelled
CI / test (ubuntu-latest, 3.12) (push) Has been cancelled
CI / test (windows-latest, 3.10) (push) Has been cancelled
CI / test (windows-latest, 3.11) (push) Has been cancelled
CI / test (windows-latest, 3.12) (push) Has been cancelled
Some checks failed
CI / lint (push) Has been cancelled
CI / test (macos-latest, 3.10) (push) Has been cancelled
CI / test (macos-latest, 3.11) (push) Has been cancelled
CI / test (macos-latest, 3.12) (push) Has been cancelled
CI / test (ubuntu-latest, 3.10) (push) Has been cancelled
CI / test (ubuntu-latest, 3.11) (push) Has been cancelled
CI / test (ubuntu-latest, 3.12) (push) Has been cancelled
CI / test (windows-latest, 3.10) (push) Has been cancelled
CI / test (windows-latest, 3.11) (push) Has been cancelled
CI / test (windows-latest, 3.12) (push) Has been cancelled
This commit is contained in:
commit
612936a00b
540 changed files with 174136 additions and 0 deletions
91
docs/adr/ADR-0002-headless-gui-dep-split.md
Normal file
91
docs/adr/ADR-0002-headless-gui-dep-split.md
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
# ADR-0002 — Split pyproject dependencies into headless base and `gui` optional extra
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| **Status** | Accepted |
|
||||
| **Date** | 2026-06-15 |
|
||||
| **Author** | ogunc |
|
||||
|
||||
---
|
||||
|
||||
## 1. Context
|
||||
|
||||
`otko.core` is pure Pydantic v2 (no Qt, no OpenSeesPy imports — stated
|
||||
explicitly in `core/__init__.py`). `otko.services` adds NumPy, h5py, and
|
||||
OpenSeesPy for headless computation. Together, these two packages can be used from
|
||||
scripts, Jupyter notebooks, and web backends **without any Qt or 3D-rendering stack**.
|
||||
|
||||
Before this ADR, every `pip install otko` pulled in PySide6, pyvista,
|
||||
pyvistaqt, vtk, pyqtgraph, and imageio — roughly 800 MB of GUI/visualization
|
||||
packages — even when only the headless computation layer was needed. Web backends and
|
||||
CI machines without a display had to work around this with `--no-deps`, which is
|
||||
fragile and skips genuine compute-layer deps (numpy, h5py) too.
|
||||
|
||||
## 2. Decision
|
||||
|
||||
Split `[project.dependencies]` into two tiers in `pyproject.toml`:
|
||||
|
||||
### Headless base (`pip install -e .`)
|
||||
|
||||
Packages imported by `core/` and the non-Qt parts of `services/`:
|
||||
|
||||
| Package | Where used |
|
||||
|---------|-----------|
|
||||
| `pydantic>=2.5` | All `core/` modules, `material_tester.py` |
|
||||
| `numpy>=1.26` | `services/` computation modules (7 files) |
|
||||
| `h5py>=3.10` | `opensees_runner._run_transient()`, `TransientResults` accessors |
|
||||
| `openseespy==3.8.0.0` | Lazy import in `OpenSeesRunner.__init__` |
|
||||
| `openseespywin==3.8.0.0 ; sys_platform=='win32'` | Windows DLL companion |
|
||||
|
||||
### GUI extra (`pip install -e ".[gui]"`)
|
||||
|
||||
Packages only needed by `views/`, `viewmodels/`, `commands/`, `qt_workers.py`,
|
||||
and `animation_export.py` (which drives a live PyVista plotter):
|
||||
|
||||
`PySide6`, `pyvista`, `pyvistaqt`, `vtk`, `pyqtgraph`, `imageio[ffmpeg]`,
|
||||
`scipy` (forward-compat, currently a phantom dep), `pandas` (same).
|
||||
|
||||
## 3. Consequences
|
||||
|
||||
- **Desktop developers** install with `pip install -e ".[gui,dev]"`. No change to
|
||||
what gets installed; only the install command changes from `.[dev]` → `.[gui,dev]`.
|
||||
- **Web backends / scripts / notebooks** install with `pip install -e .` (or
|
||||
`pip install otko`) and get a lean ~50 MB environment.
|
||||
- **otko-web** can drop the `--no-deps` workaround and install the
|
||||
package normally. The web backend's `requirements.txt` no longer needs to list
|
||||
pydantic/numpy/h5py separately — they come from the base install.
|
||||
- **scipy and pandas** are listed under `[gui]` as phantom deps (currently never
|
||||
imported anywhere in the codebase). They are kept to avoid surprise breakage if a
|
||||
future feature adds them; audited and flagged on 2026-06-15.
|
||||
|
||||
## 4. Verification
|
||||
|
||||
After installing only the base set:
|
||||
|
||||
```python
|
||||
import sys
|
||||
from otko.core import Project
|
||||
from otko.services.opensees_runner import OpenSeesRunner
|
||||
from otko.services.material_tester import test_uniaxial_material
|
||||
|
||||
# Run a modal analysis on the bundled two-storey shear frame example
|
||||
import json
|
||||
from pathlib import Path
|
||||
from otko.core import ModalCase
|
||||
|
||||
data = json.loads(Path("examples/eigen_two_storey_shear_frame.osmodel").read_text())
|
||||
project = Project.model_validate(data)
|
||||
modal_case = next(c for c in project.analyses if isinstance(c, ModalCase))
|
||||
runner = OpenSeesRunner(project)
|
||||
runner.build()
|
||||
results = runner._run_modal(modal_case)
|
||||
|
||||
assert len(results.eigenvalues) == 2
|
||||
assert all(ev > 0 for ev in results.eigenvalues)
|
||||
|
||||
gui_packages = {"PySide6", "pyvista", "pyvistaqt", "vtk", "pyqtgraph"}
|
||||
assert not gui_packages.intersection(sys.modules), \
|
||||
f"GUI package imported: {gui_packages & sys.modules.keys()}"
|
||||
|
||||
print("PASS — headless modal analysis complete, no GUI packages imported")
|
||||
```
|
||||
Loading…
Reference in a new issue