Skip to main content

TUI for batch IDEA StatiCa connection reporting and white-label export

Project description

statica-reporter

A terminal UI (TUI) for batch IDEA StatiCa connection reporting. Browse multiple .ideaCon projects and their connections in a tree, glance at per-connection details, build an ordered report selection, and export in four formats.

Run

# TUI (interactive)
uvx --from . statica-reporter          # before publishing
# uvx statica-reporter                 # once published to PyPI

# Headless batch (preserves the original main.py workflow)
uvx --from . statica-reporter-batch --input-dir inputs --output-dir out --json

Requires a running IDEA StatiCa Connection REST service. The TUI attaches to one at http://localhost:5000 by default; if none is reachable it offers to start a detected local installation (or accept a custom URL).

Features

  • Browse: tree of projects → connections with status glyphs; lazy two-pane detail (status + per-category checks, design forces, geometry counts). Press Enter to fetch, c to run CBFEM analysis.
  • Report builder: move connections from an Available tree into an ordered Selected list (Space/Enter add, A add all, J/K reorder, d remove).
  • Export (combined by default, optional split-per-connection):
    1. StatiCa PDF (native multi-connection report, grouped per project)
    2. Connection summary docx (one table: ID, isometric view, forces, checks)
    3. JSON data dump (raw results)
    4. Bound white-label docx — all selected reports concatenated and run through Pandoc with a blank reference document, so headings/tables map to stock Word styles and inherit a company template on paste (with TOC + bookmarks).
  • Workspaces: save/open named workspaces (added projects, selection, output dir, export prefs) under %APPDATA%/statica-reporter/workspaces.

Architecture

  • statica_reporter/core/ — UI-free engine (service, client, analysis, exports, rendering, summary_docx, bound_report). Fully unit-tested without a live service.
  • statica_reporter/tui/ — Textual app, screens, widgets.
  • statica_reporter/cli.py — headless batch entry point.
  • statica_reporter/workspace.py — named workspace persistence.

Run the tests with uv run pytest.

The legacy root-level main.py and report_generator.py are superseded by the package (migrated into core/); they remain only for reference and can be removed.


IDEA StatiCa Connection API — Developer Reference

This document captures everything learned from working against the live API (server v26.0.1.2450, Python client v26.0.0.3314) so future development doesn't have to rediscover it.


Setup

Install the client

uv add ideastatica-connection-api
# or: pip install ideastatica-connection-api

Prerequisites

The API requires a running IDEA StatiCa REST service. In this project the server is already running at http://localhost:5000. Docs for the running instance are available at http://localhost:5000/api.


Connecting

Use ConnectionApiServiceAttacher as a context manager. It handles session lifecycle automatically (client registration and cleanup on exit).

import ideastatica_connection_api.connection_api_service_attacher as connection_api_service_attacher

BASE_URL = "http://localhost:5000"

with connection_api_service_attacher.ConnectionApiServiceAttacher(BASE_URL).create_api_client() as api_client:
    # all work happens here
    pass

The api_client object exposes every API group as an attribute:

Attribute Purpose
api_client.project Open, close, query projects
api_client.connection Query and modify connections
api_client.calculation Run analysis, fetch results
api_client.report Export PDF / Word / HTML
api_client.load_effect Manage load cases
api_client.material Steel, bolt, weld, concrete materials
api_client.member Connection members
api_client.operation Connection operations (welds, bolts, etc.)
api_client.parameter Parametric values
api_client.template Connection templates
api_client.settings Project settings
api_client.export IOM / IFC export
api_client.presentation 3D scene data

Core workflow

1. Open a project

api_client.project.open_project_from_filepath(r"C:\path\to\file.ideaCon")
project_id = api_client.project.active_project_id  # str UUID, set automatically

2. List connections

project_data = api_client.project.get_project_data(project_id)
# project_data.connections -> list of ConConnection
for conn in project_data.connections:
    print(conn.id, conn.name)   # id is an int

3. Check if a connection is already analyzed

There is no explicit "status" field. Check by calling get_results and inspecting check_res_summary:

results = api_client.calculation.get_results(project_id, [conn_id])
already_analyzed = (
    results
    and results[0]
    and results[0].check_res_summary is not None
)

ConnectionCheckRes fields: check_res_summary, check_res_plate, check_res_weld, check_res_bolt, check_res_anchor, check_res_concrete_block, buckling_results, name, connection_id, id, messages.

4. Run analysis

summaries = api_client.calculation.calculate(project_id, [conn_id])
# returns List[ConResultSummary]
# ConResultSummary fields: id, passed, result_summary

calculate accepts a plain List[int] of connection IDs — pass multiple IDs to batch.

Note: The official documentation shows a ConCalculationParameter object, but this class does not exist in the installed Python client. Pass a plain list directly.

5. Fetch raw JSON results

raw_list = api_client.calculation.get_raw_json_results(project_id, [conn_id])
# returns List[str], one JSON string per connection ID
import json
data = json.loads(raw_list[0])

Top-level keys in the returned object: codeType, plates, platesDeformation, bolts, welds, anchors, concreteBlock, bucklingResults, and others depending on connection type.

6. Fetch structured results

results = api_client.calculation.get_results(project_id, [conn_id])
# returns List[ConnectionCheckRes]
summary = results[0].check_res_summary   # ConResultSummary
plates  = results[0].check_res_plate     # list of CheckResPlate
welds   = results[0].check_res_weld      # list of CheckResWeld
bolts   = results[0].check_res_bolt      # list of CheckResBolt

7. Export reports

# PDF — returns bytes, write manually
pdf_bytes = api_client.report.generate_pdf(project_id, conn_id)  # conn_id is int
with open("report.pdf", "wb") as f:
    f.write(pdf_bytes)

# Word
docx_bytes = api_client.report.generate_word(project_id, conn_id)

# HTML zip
zip_bytes = api_client.report.generate_html_zip(project_id, conn_id)

# Batch PDF (all connections at once)
# Note: "mutliple" is a typo in the API itself — use it exactly as shown
pdf_bytes = api_client.report.generate_pdf_for_mutliple(project_id, [conn_id_1, conn_id_2])

Note: The return type annotation says None for generate_pdf — this is wrong. It returns bytes.

8. Close the project

api_client.project.close_project(project_id)

Always close when done. Unclosed projects remain in the server's memory.


Units

The API never returns unit labels. There are no unit-related classes, settings, or fields anywhere in the package. All raw numeric values are in SI units, regardless of the project's design code (American, Eurocode, etc.):

Quantity Unit
Length / dimension m
Stress / pressure / strength Pa
Force N
Moment N·m

Example cross-check from a real result (codeType: "american", material A992):

  • thickness: 0.04 → 40 mm plate ✓
  • materialFy: 344_740_000 → 344.7 MPa ≈ 50 ksi ✓
  • materialModulusOfElasticity: 200_000_000_000 → 200 GPa ✓

Settings

get_settings returns a flat Dict[str, object] keyed by slash-separated paths:

settings = api_client.settings.get_settings(project_id)
# e.g. settings["calculationCommon/Checks/Shared/LimitPlasticStrain"] -> 0.05

# Search by keyword
settings = api_client.settings.get_settings(project_id, search="mesh")

Update a setting:

api_client.settings.update_settings(project_id, {
    "calculationCommon/Checks/Shared/LimitPlasticStrain": 0.03
})

Other useful APIs

Load effects

load_effects = api_client.load_effect.get_load_effects(project_id, conn_id)

Materials

steels   = api_client.material.get_steel_materials(project_id)
bolts    = api_client.material.get_bolt_grade_materials(project_id)
sections = api_client.material.get_cross_sections(project_id)

Export to IOM/IFC

iom_xml  = api_client.export.export_iom(project_id, conn_id)
ifc_data = api_client.export.export_ifc(project_id, conn_id)

3D scene data

scene_json = api_client.presentation.get_data_scene3_d_text(project_id, conn_id)

Complete working example

This is the pattern used in main.py:

import glob, json, os
import ideastatica_connection_api.connection_api_service_attacher as connection_api_service_attacher

BASE_URL = "http://localhost:5000"

with connection_api_service_attacher.ConnectionApiServiceAttacher(BASE_URL).create_api_client() as api_client:
    api_client.project.open_project_from_filepath(r"inputs\myfile.ideaCon")
    project_id = api_client.project.active_project_id

    project_data = api_client.project.get_project_data(project_id)

    for conn in project_data.connections:
        conn_id = conn.id  # int

        # Skip calculation if already done
        results = api_client.calculation.get_results(project_id, [conn_id])
        if not (results and results[0] and results[0].check_res_summary is not None):
            api_client.calculation.calculate(project_id, [conn_id])

        # PDF report
        pdf_bytes = api_client.report.generate_pdf(project_id, conn_id)
        with open(f"reports/{conn.name}.pdf", "wb") as f:
            f.write(pdf_bytes)

        # Raw JSON data
        raw = api_client.calculation.get_raw_json_results(project_id, [conn_id])
        parsed = json.loads(raw[0])
        with open(f"data/{conn.name}.json", "w") as f:
            json.dump(parsed, f, indent=2)

    api_client.project.close_project(project_id)

Gotchas

  • ConCalculationParameter does not exist in the installed client. Pass List[int] directly to calculate and get_raw_json_results.
  • generate_pdf return type is annotated as None but actually returns bytes. Open the file in "wb" mode.
  • All values are SI — convert to display units in your own layer if needed.
  • Always close projects — the server holds them in memory until explicitly closed or the session ends.
  • active_project_id is set automatically after open_project_from_filepath. You do not need to parse the return value.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

statica_reporter-0.1.0.tar.gz (117.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

statica_reporter-0.1.0-py3-none-any.whl (50.1 kB view details)

Uploaded Python 3

File details

Details for the file statica_reporter-0.1.0.tar.gz.

File metadata

  • Download URL: statica_reporter-0.1.0.tar.gz
  • Upload date:
  • Size: 117.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for statica_reporter-0.1.0.tar.gz
Algorithm Hash digest
SHA256 14a16ef8975237ede9f9c10301d6183ab02d2dfaa08410ea0789f932bcd002b2
MD5 527f15e79313d7e2f5b4a9492ee076e7
BLAKE2b-256 7cc9bb993e20ce4fc84f33b63b4861f322209df19264b47b0185137aed48836e

See more details on using hashes here.

Provenance

The following attestation bundles were made for statica_reporter-0.1.0.tar.gz:

Publisher: release.yml on Mark-Milkis/statica-reporter

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file statica_reporter-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for statica_reporter-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 451d911b347e194e95183357ce0ada91ee36b138ee8eeac4153e761da530ffae
MD5 05dfb81e98c2a9860d9a20bed85a8c7d
BLAKE2b-256 c1a75655b166e0838d641633ad5522c37f71eefa3c8533fca019f809ef764c53

See more details on using hashes here.

Provenance

The following attestation bundles were made for statica_reporter-0.1.0-py3-none-any.whl:

Publisher: release.yml on Mark-Milkis/statica-reporter

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page