Metadata-Version: 2.4
Name: fers_calculations
Version: 0.2.54
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Rust
Classifier: License :: OSI Approved :: BSD License
Classifier: Operating System :: OS Independent
License-File: LICENSE
Summary: High-performance Rust-backed calculations for FERS.
Keywords: rust,python,mechanical engineering,calculations
Home-Page: https://ferscloud.com
Author-email: Jeroen Hermsen <jhermsen@serrac.nl>
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM

# FERS_calculations

`FERS_calculations` is a high-performance library for Rust-backed calculations in mechanical engineering. It can process JSON input files to deliver fast and accurate results. While it can be run as a standalone tool, integration with `FERS_core` simplifies input creation and workflow management.

## Features

- **Standalone Functionality:** Run directly by providing a valid JSON input file.
- **Rust-Powered Performance:** Designed for speed and reliability in computational tasks.
- **Python Integration:** Seamless integration with `FERS_core` for easy preprocessing and result handling.
- **Engineer-Friendly Design:** Minimal coding effort required for complex structural engineering calculations.

---

## Installation

```bash
pip install fers_calculations
```

This installs the pre-built Rust bindings -- no Rust toolchain required.

## Usage

### Standalone (Python)

You can call `fers_calculations` directly from Python without `FERS_core`:

```python
import fers_calculations

# Load your JSON input
with open("001_cantilever_with_end_load.json") as f:
    json_data = f.read()

# Run the analysis
results_json = fers_calculations.calculate_from_json(json_data)

# Save the results
with open("results.json", "w") as f:
    f.write(results_json)
```

### Premium licensing and timeouts

Passing `api_key` unlocks Premium model limits. That is the only thing that makes
the library contact the network — omit it and no request is ever sent.

Because a licence check is a network call, it is bounded. If ferscloud.com does
not answer within `license_timeout` seconds (default 30) the call raises
`fers_calculations.FersTimeoutError` **before the solve starts**, so retrying is
always safe:

```python
import fers_calculations

try:
    fers_calculations.calculate_to_file(
        json_data, "results.json", api_key=KEY, license_timeout=60
    )
except fers_calculations.FersTimeoutError:
    ...  # transient — retry or skip this model
```

`FersTimeoutError` subclasses the built-in `TimeoutError`, so `except TimeoutError`
catches it too. A definitive failure — an invalid key, a non-premium account, an
unreachable host — raises `RuntimeError` instead, since retrying those is pointless.

`license_timeout` bounds the **licence handshake only**, not the solve. To put a
hard ceiling on a whole solve, run it in a killable subprocess.

Two environment variables are read (real process environment only — `.env` files
are loaded by the CLI binary, never by this extension module):

| Variable | Purpose | Default |
|---|---|---|
| `FERS_LICENSE_TIMEOUT` | Default `license_timeout`, in seconds | `30` |
| `FERS_CLOUD_URL` | Base URL of the licence API | `https://ferscloud.com` |

### With FERS_core (recommended)

For a more ergonomic workflow, install `FERS_core` which handles model creation, calling the Rust engine, and post-processing / visualisation:

```bash
pip install fers-core
```

```python
from fers_core import FERS

model = FERS.from_json("001_cantilever_with_end_load.json")
model.calculate()
model.plot_results_3d()
```

See [FERS_core on PyPI](https://pypi.org/project/fers-core/) for full documentation.

