3.3 KiB
AGENTS.md — otko
Pre-alpha SAP2000-style desktop GUI for OpenSeesPy. Python 3.10+; Windows requires 3.12+ (openseespywin==3.8.0.0 has no 3.11 wheel). Solver pinned: openseespy==3.8.0.0.
Install
pip install -e ".[gui,dev]" # desktop: Qt + PyVista + dev tools
pip install -e . # headless: core + services only, no Qt (scripts, notebooks, web backends)
python -m otko # launch GUI (src/otko/app.py:run)
scipy/pandas in [gui] extras are phantom deps (not imported as of 2026-06) — do not add imports expecting them.
Architecture (enforced in review — see PR template)
Strict one-way MVVM + services: views → viewmodels → services → core.
core/(entities:project.py,geometry/,materials/,sections/,loads/,analysis/,catalog/): stdlib + numpy + pydantic only. No Qt, no openseespy. Period.services/(opensees_runner.py,persistence.py,results.py, ...): may use core + h5py + openseespy. No Qt.views/: PySide6/pyvistaqt only. No directimport openseespy— go through a service.viewmodels/bridges core↔Qt (signals,QUndoStack);commands/holdsQUndoCommandsubclasses.- Rules: public functions need type hints + docstring; new domain entities go through Pydantic validation; ops >50 ms run off the GUI thread (
AnalysisWorkerin QThread, cancel viaisInterruptionRequested(), results cross threads as lightweightResultsHandleto HDF5).
Runner emits OpenSeesPy commands in fixed order (docs/architecture.md): wipe → model → node → fix → material → section → geomTransf → element → timeSeries → pattern/load → recorder → system/numberer/... → analyze. Never reorder.
Branches
- Do all feature/fix work on
develop(or short-lived branches offdevelop, merged back into it).mainis release-only — never commit directly to it.
Verify (in this order)
ruff check src tests
ruff format src tests # line-length 100, E501 ignored
mypy src/otko/core src/otko/services
pytest -m "not slow" # CI gate: lint → this, on 3.10/3.11/3.12 × ubuntu/windows/macos
Focused runs: pytest tests/unit (pure logic, ms), pytest tests/gui -k <name> (pytest-qt, needs display), pytest tests/integration -k <name> (real OpenSeesPy runs). Single test: pytest tests/unit/test_project.py::test_name -q. Markers: gui, slow. Linux GUI tests need xvfb-run -a pytest ... plus system Qt libs (see ci.yml apt list).
Notes: tests/conftest.py auto-ops.wipe()s the OpenSees domain between tests (lazy import so core tests stay Qt/OpenSees-free). Coverage omits views/. Commit style: Conventional Commits (feat:, fix:, ...). pre-commit install runs ruff + mypy (mypy hook scoped to core|services|viewmodels).
Examples & persistence
examples/*.pyare source of truth;examples/*.osmodelare generated artifacts (checked in). Never hand-edit.osmodel— change the script and regen:python examples/cantilever.py(each script saves, reloads, asserts clean round-trip).- Projects persist as single Pydantic-validated JSON
.osmodel(diffable); analysis output goes to*.osresults.h5(HDF5, one group per case). - Quick smoke: open
examples/cantilever.osmodel→ runTip-Load→ M3 peaks 50 kN·m at fixed end.