Metadata-Version: 2.3
Name: civix
Version: 0.9.0
Summary: Structural-engineering calculation library where Jupyter notebooks are the living, reviewable deliverable.
Author: mohamadalitellawi
Author-email: mohamadalitellawi <mohamadalitellawi@gmail.com>
License: MIT License
         
         Copyright (c) 2025 mohamadalitellawi
         
         Permission is hereby granted, free of charge, to any person obtaining a copy
         of this software and associated documentation files (the "Software"), to deal
         in the Software without restriction, including without limitation the rights
         to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
         copies of the Software, and to permit persons to whom the Software is
         furnished to do so, subject to the following conditions:
         
         The above copyright notice and this permission notice shall be included in all
         copies or substantial portions of the Software.
         
         THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
         IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
         FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
         AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
         LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
         OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
         SOFTWARE.
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: Topic :: Scientific/Engineering
Classifier: Programming Language :: Python :: 3
Requires-Dist: httpx>=0.28
Requires-Dist: loguru>=0.7.3
Requires-Dist: numpy>=2.0
Requires-Dist: openpyxl>=3.1.5
Requires-Dist: pandas>=2.2
Requires-Dist: plotly>=5.20
Requires-Dist: scipy>=1.13
Requires-Dist: civix[notebook,streamlit,host] ; extra == 'all'
Requires-Dist: pythonnet>=3.1.0 ; extra == 'host'
Requires-Dist: laspy[lazrs]>=2.5 ; extra == 'host'
Requires-Dist: pyclipper>=1.4 ; extra == 'host'
Requires-Dist: handcalcs>=1.11.0 ; extra == 'notebook'
Requires-Dist: jupytext>=1.16 ; extra == 'notebook'
Requires-Dist: markdown>=3.10.2 ; extra == 'notebook'
Requires-Dist: matplotlib>=3.10.9 ; extra == 'notebook'
Requires-Dist: nbformat>=5.10.4 ; extra == 'notebook'
Requires-Dist: notebook>=7.5.6 ; extra == 'notebook'
Requires-Dist: streamlit>=1.58.0 ; extra == 'streamlit'
Requires-Dist: pydantic>=2.0 ; extra == 'streamlit'
Requires-Dist: streamlit-pydantic>=0.6.0 ; extra == 'streamlit'
Requires-Python: >=3.12
Project-URL: Homepage, https://github.com/mohamadalitellawi/civix
Project-URL: Repository, https://github.com/mohamadalitellawi/civix
Provides-Extra: all
Provides-Extra: host
Provides-Extra: notebook
Provides-Extra: streamlit
Description-Content-Type: text/markdown

# civix

A structural-engineering design library for Python where Jupyter notebooks are
the primary deliverable — living calculation documents suitable for review and
submission.

> Status: **foundation cycle**. The cross-cutting infrastructure (errors,
> logging, notebook display, and the Quarto export pipeline) is in place;
> structural-domain modules (codes, elements, materials) arrive in later cycles.

Civix has two rendering paths:

- **`civix.display`** — the *live* view inside a running notebook (self-rendering
  PASS/FAIL cards, headers, input tables).
- **`civix.report`** — the *printed* deliverable: scaffold a Quarto project and render
  a notebook to PDF/HTML/docx.

Plus domain tooling:

- **`civix.workflows.etabs2safe` + `hosts/etabs2safe/`** — ETABS → SAFE raft
  pipeline built on `civix.csilib`: read per-building live ETABS models — the
  attached one, or **N model files opened sequentially in one launched
  instance** (TOML project config with per-building shifts, solved from point
  pairs or given directly; opt-in analyse of result-less models) — place them
  into one SAFE frame with full 6-DOF reaction handling, emit a validated
  raft JSON + Plotly overlay, and build/run the SAFE mat model. See
  `docs/workflows/etabs2safe-guide.md`.
- **`civix.csilib` + `hosts/csilib/`** — object-level CSI OAPI wrapper for
  ETABS, SAP2000 and SAFE: typed enums, frozen dataclasses, pandas DataFrames,
  context-managed launch/attach with a hardened connection recipe, and SAFE's
  database-table layer as DataFrame in/out. Configured by the repo-root
  `csilib.toml`. See [`src/civix/csilib/README.md`](src/civix/csilib/README.md)
  and `docs/csilib/csilib-guide.md`.
- **`civix.site` + `hosts/grasshopper/`** — Rhino/Grasshopper site tools:
  point-cloud ground-Z extraction (LAS/LAZ) and Revit toposolid break-line
  creasing. Pure engines are unit-tested here; thin GH components run on the
  host. See `docs/gh-tools-cookbook.md`.
- **`app/csi_safe_builder/`** — a Streamlit control panel over the
  `civix.workflows.etabs2safe` pipeline (read the attached ETABS model, or
  multiple model files with per-building shifts → assemble the raft → build
  the SAFE `.fdb`), run on the Windows/SAFE host. Not shipped in the wheel.
  See [`app/csi_safe_builder/README.md`](app/csi_safe_builder/README.md).

## Quickstart

```bash
uv sync                  # core library (numpy/scipy/pandas/plotly included)
uv sync --extra notebook # add Jupyter + handcalcs (optional, needed to run notebooks)
uv run poe demo          # executes the foundation reporting demo notebook
```

In a notebook:

```python
from civix.display import setup_notebook, CheckResult, CalculationReport

setup_notebook(project_name="Office Building A", engineer="J. Doe")

report = CalculationReport(title="Beam B-101")
report.add(CheckResult("Bending", unity_ratio=0.73, demand=180.0,
                       capacity=245.6, demand_unit="kNm", capacity_unit="kNm"))
report  # renders a styled PASS/FAIL report
```

## Exporting a PDF

Scaffold a Quarto project, then render a notebook. Export needs the external
[Quarto](https://quarto.org) CLI plus a LaTeX engine (e.g. TinyTeX).

```python
from civix.report import init_calc_project, render_report

init_calc_project("calcs", include_sample=True)   # writes Quarto templates
render_report("calcs/sample-calcsheet.ipynb")      # -> calcs/sample-calcsheet.pdf
```

The scaffold also has a CLI:

```bash
uv run python -m civix.report calcs --sample
```

## Command-line tools

Installing civix also installs three console commands:

```bash
civix-health              # read-only doctor: version, optional extras, Quarto CLI,
                          # csilib.toml discovery (never launches ETABS/SAP2000/SAFE)
civix-init-config [DIR]   # scaffold a starter csilib.toml (commented defaults) into DIR
civix-init-calc DIR       # scaffold the Quarto calc templates (same as python -m civix.report)
```

All three work on a bare `pip install civix` — optional extras are only detected,
never imported.

For a complete worked example — an ACI 318M-25 (SI) flexure calc note that pairs
[`handcalcs`](https://github.com/connorferster/handcalcs) equation rendering with
civix `CheckResult`/`CalculationReport` cards — see
[`notebooks/examples/sample-calcsheet.ipynb`](notebooks/examples/sample-calcsheet.ipynb)
and render it with `uv run --extra notebook quarto render
notebooks/examples/sample-calcsheet.ipynb --to pdf`.

## Conventions

Notebooks are submission-grade calculation documents. Units are **never encoded
in identifier names** — use clean engineering symbols (`A_s`, `M_u`, `f_c`) and
annotate the unit on the value (a `handcalcs` trailing comment, the value string
in `calc_input_table`, `demand_unit`/`capacity_unit` on `CheckResult`, or a
library docstring). The default system is metric: N/mm/MPa for section and
material values, kN/m/kPa/kN·m for loads and spans. Convert at boundaries; never
mix unit systems silently. Full discipline lives in
[`docs/calc-note-style-guide.md`](docs/calc-note-style-guide.md) and `CLAUDE.md`.

## Development

Dev tasks run through [Poe the Poet](https://poethepoet.natn.io) (`[tool.poe.tasks]`
in `pyproject.toml`) so they work identically on Windows, macOS and Linux:

```bash
uv sync --extra all    # dev setup: core + every extra (the dev group holds tools/stubs only)
uv run poe check       # format, lint, type-check, test (675 tests; 34 live-vendor tests skip unless --run-* flags are passed)
uv run poe gh39-check  # syntax-guard the civix.site engines + GH host scripts on CPython 3.9
```

Run the live-vendor integration suites (on the Windows/CSI host):

```bash
uv run pytest tests/integration/csilib tests/integration/workflows --run-etabs --run-sap2000 --run-safe
```

Run the Streamlit app (on the Windows/SAFE host):

```bash
uv run --extra host --extra streamlit streamlit run app/csi_safe_builder/main.py
```

## Repository layout

```text
src/civix/                 # the installable package (ships in the wheel)
├─ exceptions.py           #   CivixError hierarchy
├─ log_config.py           #   loguru setup
├─ display/                #   live in-notebook PASS/FAIL rendering
├─ report/                 #   Quarto PDF/HTML/docx export (+ templates/ package data)
├─ utils/                  #   formatting + validation helpers
├─ csilib/                 #   CSI OAPI wrapper — ETABS/SAP2000/SAFE (pythonnet via the optional `host` extra)
├─ workflows/              #   cross-tool pipelines on csilib
│  └─ etabs2safe/          #     ETABS → SAFE raft pipeline (optional `host` extra)
├─ site/                   #   Grasshopper engines (laspy/pyclipper via the optional `host` extra)
│  ├─ pointcloud/          #     LAS/LAZ ground-Z KD-tree engine + origin-shift
│  └─ topo/                #     Revit toposolid break-line helpers
└─ core/ elements/ codes/ loads/   # structural-domain stubs (later cycles)

hosts/                     # host-only adapter scripts — NOT in the wheel, ruff/ty-excluded
├─ etabs2safe/             #   raft-pipeline entry scripts + AutoCAD outline LISP helpers
├─ csilib/                 #   csilib diagnostics, vendor gates, notebook generators, API index
└─ grasshopper/            #   Rhino/Revit GH components (load engines by file path)
   └─ topo_breaklines/

app/                       # host-level Streamlit UIs — NOT in the wheel, ty-excluded
└─ csi_safe_builder/       #   settings.py / actions.py / main.py over the etabs2safe workflow

tests/
├─ unit/                   # mirrors library modules (test_workflows/, test_site/, …)
├─ integration/            # external toolchains — Quarto, plus workflows/ + csilib/
└─ notebooks/              # deliverable calc-note benchmark suites

docs/
├─ workflows/              # etabs2safe invariants guide + OAPI references
├─ csilib/                 # civix.csilib binding domain reference (csilib-guide.md)
├─ gh-tools-cookbook.md    # the two-layer Grasshopper tool pattern
├─ standards/              # binding engineering / API / debugging protocols
└─ superpowers/            # implementation plans + design specs
```

Three deliberately separate layers: **engines** (`src/civix/…`, pure, tested, in
the wheel), **hosts** (`hosts/…`, thin vendor-API adapters that run only inside
ETABS/SAFE or Rhino/Revit), and **apps** (`app/…`, host-level Streamlit UIs over
the engines). Only `src/civix/…` ships in the wheel; hosts and apps live outside
it and — like the host scripts — call the engines rather than reimplement them.
