Metadata-Version: 2.4
Name: mrg-iot
Version: 1.2.1
Summary: IoT Testbed Experiment Automation CLI for MergeTB / Sphere Testbed
Author: Sphere / NEU IoT Testbed contributors
License: MIT
Project-URL: Homepage, https://gitlab.com/sphere-neu/mrg-iot
Project-URL: Repository, https://gitlab.com/sphere-neu/mrg-iot
Project-URL: Issues, https://gitlab.com/sphere-neu/mrg-iot/-/issues
Keywords: iot,testbed,mergetb,sphere,automation,cli
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Science/Research
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: MacOS
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: System :: Distributed Computing
Classifier: Topic :: System :: Networking
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: bcrypt>=5.0.0
Requires-Dist: betterproto==2.0.0b7
Requires-Dist: certifi
Requires-Dist: cffi>=2.0.0
Requires-Dist: cryptography>=46.0.3
Requires-Dist: grpclib>=0.4.8
Requires-Dist: h2>=4.3.0
Requires-Dist: hpack>=4.1.0
Requires-Dist: hyperframe>=6.1.0
Requires-Dist: mergetbapi==1.3.41
Requires-Dist: multidict>=6.7.0
Requires-Dist: packaging>=25.0
Requires-Dist: paramiko>=4.0.0
Requires-Dist: pycparser>=2.23
Requires-Dist: PyNaCl>=1.6.0
Requires-Dist: python-dateutil>=2.9.0
Requires-Dist: six>=1.17.0
Requires-Dist: typing_extensions>=4.15.0
Provides-Extra: dev
Requires-Dist: astroid==4.0.1; extra == "dev"
Requires-Dist: black==25.9.0; extra == "dev"
Requires-Dist: dill==0.4.0; extra == "dev"
Requires-Dist: invoke==2.2.1; extra == "dev"
Requires-Dist: isort==7.0.0; extra == "dev"
Requires-Dist: mccabe==0.7.0; extra == "dev"
Requires-Dist: mypy_extensions==1.1.0; extra == "dev"
Requires-Dist: pathspec==0.12.1; extra == "dev"
Requires-Dist: platformdirs==4.5.0; extra == "dev"
Requires-Dist: pylint==4.0.2; extra == "dev"
Requires-Dist: pytokens==0.2.0; extra == "dev"
Requires-Dist: tomlkit==0.13.3; extra == "dev"
Requires-Dist: types-paramiko; extra == "dev"
Dynamic: license-file

# mrg-iot

A Python CLI for automating IoT testbed experiments on the
[Sphere / Merge Testbed](https://sphere-testbed.net) platform.

`mrg-iot` drives the full experiment lifecycle so you don't have to:

- Create an experiment and its network model for the selected devices.
- Realize and materialize the model.
- Create an XDC (eXperimental Data Center) and attach it to the
  materialization.
- Set up SSH port forwarding for RTSP streams and file downloads.
- (Optional) De-materialize and clean up resources when you're done.

## Installation

```bash
pipx install mrg-iot
```

(Or `pip install mrg-iot` inside a virtualenv.)

`mrg-iot` requires **Python 3.9+** and a working
[VLC](https://www.videolan.org/vlc/) install on the host for RTSP
playback — `pip` can't install VLC for you.

## Usage

### Interactive mode

```bash
mrg-iot login        # save credentials to ~/.mrg-iot/config.json
mrg-iot              # walk through the experiment flow
```

### Non-interactive mode

```bash
mrg-iot --non-interactive \
    --project neuiot \
    --devices s-echodot-1 \
    --exp-name myexp \
    --exp-desc "my experiment" \
    --realization realiot \
    --duration 1w \
    --xdc myxdc
```

### Cleanup subcommands

```bash
mrg-iot exp delete         --project neuiot --name myexp
mrg-iot exp dematerialize  --project neuiot --name myexp --realization realiot
mrg-iot xdc detach         --project neuiot --name myxdc --experiment myexp --realization realiot
mrg-iot xdc delete         --project neuiot --name myxdc
```

Run `mrg-iot --help` for the full flag list.

### Debug logging

```bash
mrg-iot --debug      # verbose logs to stderr + debug.log
```

## Input validation

The CLI validates inputs upfront so bad args fail fast rather than
deep inside a portal call:

- **Names** (`exp-name`, `realization`, `xdc`, network): start with a
  letter, lowercase letters and digits only, max 32 chars.
- **Description**: letters, digits, spaces, commas, periods, hyphens;
  max 256 chars.
- **Duration**: minimum 4 days. Accepts `1w`, `4d`, `1w2d`,
  `1 week`, etc.

## macOS SSL note

If portal calls fail with an SSL error on macOS:

```bash
export SSL_CERT_FILE="$(python -m certifi)"
export REQUESTS_CA_BUNDLE="$SSL_CERT_FILE"
```

## Development

```bash
git clone https://gitlab.com/sphere-neu/mrg-iot.git
cd mrg-iot
python3 -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"

mypy .
pylint *.py
black *.py
isort *.py
```

## License

MIT — see [LICENSE](LICENSE).
