Metadata-Version: 2.4
Name: roboai-libs-client
Version: 0.1.8
Summary: Python client SDK for the RoboAI LIBS Spectrum Simulator API.
Author: RoboAI Green
License: MIT
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Physics
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: httpx>=0.27.0
Requires-Dist: pydantic>=2.7.0
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: ruff>=0.5.0; extra == "dev"
Dynamic: license-file

# RoboAI LIBS Client

Lightweight Python client SDK for the RoboAI LIBS Spectrum Simulator API.

## Install

From PyPI:

```bash
pip install --upgrade roboai-libs-client
```

From GitHub, if you need the latest repository version:

```bash
pip install git+https://github.com/RoboAI-Green/roboai-libs-client.git
```

## Authentication

The command line and Python client require a platform Bearer token before calling
the hosted simulator. Choose one of the following setup methods.

### Option 1: interactive login

Recommended for most users:

```bash
roboai-libs auth login
```

Enter your email address, open the verification link from your mailbox, and paste
the returned `access_token` value. The token is stored locally, so future
`RoboAILIBSClient()` calls can use it automatically.

### Option 2: request a login email directly

Use this if you prefer a single command without the email prompt:

```bash
roboai-libs auth login --email you@uni.fi
```

Then open the verification link from your mailbox and paste the returned token
when prompted.

### Option 3: use an existing token

If you already have a token, validate it and store it locally:

```bash
roboai-libs auth login --token tok_...
```

Alternatively, pass it directly with `api_key=...` or the
`ROBOAI_LIBS_API_KEY` environment variable:

```bash
export ROBOAI_LIBS_API_KEY=tok_...
```

```python
client = RoboAILIBSClient(api_key="tok_...")
```

Useful authentication commands:

```bash
roboai-libs doctor
roboai-libs auth status
roboai-libs auth logout
```

## Command-line Quick Use

The command line interface is intentionally small. It is useful for checking
authentication, listing elements, exporting a quick static spectrum to CSV, and
downloading a dynamic exposure result as HDF5. Use the Python API for larger
parameter sweeps and custom workflows.

Start by logging in:

```bash
roboai-libs auth login
```

Check whether the client can reach the API and whether the configured token is
valid:

```bash
roboai-libs doctor
```

`roboai-libs auth status` only checks local token configuration. `roboai-libs
doctor` checks the API connection, validates the token if one is configured, and
queries the elements endpoint.

List available elements:

```bash
roboai-libs elements
```

Run a static nickel spectrum with default plasma settings:

```bash
roboai-libs static --element Ni --out ni.csv
```

Set the most common spectrum parameters:

```bash
roboai-libs static \
  --element Ni \
  --range 200 230 \
  --resolution 0.05 \
  --te 1 \
  --ne 1e17 \
  --out ni.csv
```

Run a simple mixture:

```bash
roboai-libs static \
  --element Ni \
  --element Fe \
  --proportion 2 \
  --proportion 1 \
  --out ni_fe.csv
```

Run a dynamic exposure and save HDF5:

```bash
roboai-libs dynamic --element Ni --out ni_dynamic.h5
```

Set the most common dynamic parameters:

```bash
roboai-libs dynamic \
  --element Ni \
  --range 200 230 \
  --resolution 0.05 \
  --integration-time 1e-6 \
  --time-resolution 100e-9 \
  --out ni_dynamic.h5
```

## Quick Start

After authentication, run a first static spectrum:

```python
from roboai_libs_client import RoboAILIBSClient

client = RoboAILIBSClient()

result = client.simulate_static(
    elements=["Ni"],
    range_min_nm=200,      # start wavelength in nm
    range_max_nm=230,      # end wavelength in nm
    resolution_nm=0.05,    # wavelength step in nm
    te_ev=1.0,
    ne_cm3=1e17,
    fwhm_nm=0.0,
)

print(result.wls[:5])
print(result.intensity[:5])
```

## Common Parameters

Most spectrum requests use the following parameters:

| Parameter | Meaning |
| --- | --- |
| `elements` | Element symbols to include, for example `["Ni"]` or `["Ni", "Fe"]`. |
| `proportions` | Relative element proportions. Values are normalized automatically, so `[2, 1]` becomes 2/3 and 1/3. |
| `range_min_nm` | Start wavelength of the simulated range, in nanometres. |
| `range_max_nm` | End wavelength of the simulated range, in nanometres. |
| `resolution_nm` | Wavelength spacing, in nanometres. Smaller values give finer spectra but require more computation. |
| `te_ev` | Electron temperature in electronvolts. |
| `ne_cm3` | Electron number density in cm^-3. |
| `fwhm_nm` | Instrumental broadening full width at half maximum, in nanometres. Use `0.0` for no instrumental broadening. |
| `instrument_profile` | Instrument broadening profile, usually `"gaussian"` or `"lorentzian"`. |
| `integration_time_s` | Total simulated exposure time for dynamic simulations, in seconds. |
| `time_resolution_s` | Time step for dynamic simulations, in seconds. |

## Examples

### 1. List available elements

```python
from roboai_libs_client import RoboAILIBSClient

client = RoboAILIBSClient()

elements = client.list_elements()
print(elements[:20])
```

### 2. Static spectrum

```python
from roboai_libs_client import RoboAILIBSClient

client = RoboAILIBSClient()

result = client.simulate_static(
    elements=["Ni"],
    range_min_nm=280,
    range_max_nm=330,
    resolution_nm=0.05,
    te_ev=1.0,
    ne_cm3=1e17,
)

print(len(result.wls), len(result.intensity))
print(result.lines[:3])
```

### 3. Mixture spectrum

`proportions` do not need to sum to 1. The client normalizes them before sending
the request.

```python
from roboai_libs_client import RoboAILIBSClient

client = RoboAILIBSClient()

result = client.simulate_static(
    elements=["Ni", "Fe"],
    proportions=[2, 1],
    range_min_nm=280,
    range_max_nm=330,
    resolution_nm=0.05,
    te_ev=1.0,
    ne_cm3=1e17,
)

print(result.wls[:5])
print(result.intensity[:5])
```

### 4. Instrument broadening

```python
from roboai_libs_client import RoboAILIBSClient

client = RoboAILIBSClient()

result = client.simulate_static(
    elements=["Ni"],
    range_min_nm=280,
    range_max_nm=330,
    resolution_nm=0.05,
    te_ev=1.0,
    ne_cm3=1e17,
    fwhm_nm=0.10,
    instrument_profile="gaussian",
)

print(result.instrument_profile, result.fwhm_nm)
```

### 5. Dynamic exposure

```python
from roboai_libs_client import RoboAILIBSClient

client = RoboAILIBSClient()

result = client.simulate_exposure(
    elements=["Ni"],
    range_min_nm=200,
    range_max_nm=230,
    resolution_nm=0.05,
    te_ev=1.0,
    ne_cm3=1e17,
    fwhm_nm=0.0,
    integration_time_s=1e-6,
    time_resolution_s=100e-9,
)

print(len(result.time_vector))
print(len(result.snapshot_matrix), len(result.snapshot_matrix[0]))
print(len(result.total_exposure))
```

`snapshot_matrix` is the time-wavelength intensity matrix. `total_exposure` is
the time-integrated spectrum.

### 6. Save dynamic HDF5

```python
from roboai_libs_client import RoboAILIBSClient, ExposureRequest

client = RoboAILIBSClient()

request = ExposureRequest(
    elements=["Ni"],
    range_min_nm=200,
    range_max_nm=230,
    resolution_nm=0.05,
    integration_time_s=1e-6,
    time_resolution_s=100e-9,
)

path = client.save_dynamic_hdf5("ni_dynamic.h5", request)
print(f"Saved {path}")
```

The current platform API serves HDF5 for completed dynamic exposure jobs. Static
spectra are available through `simulate_static()` as typed JSON results.

## API Reference

Main client methods:

- `RoboAILIBSClient()` creates a client using the stored login token or
  `ROBOAI_LIBS_API_KEY`.
- `list_elements()` returns element symbols available from the hosted simulator.
- `simulate_static(...)` returns a `StaticSpectrumResult`.
- `simulate_exposure(...)` returns an `ExposureResult`.
- `save_dynamic_hdf5(path, request)` submits a dynamic exposure job, waits for it,
  downloads the HDF5 result, and returns the written `Path`.

Typed request models:

- `StaticSpectrumRequest`
- `ExposureRequest`
- `PlasmaConfig`
- `TemporalConfig`

Typed result models:

- `StaticSpectrumResult`
- `ExposureResult`

## License

MIT License.
