# API reference

## `RBridge`

### Constructor

```python
RBridge(
    r_executable: str | None = None,
    startup_timeout: float = 15.0,
    call_timeout: float = 60.0,
    env: dict[str, str] | None = None,
    r_libs: list[str] | None = None,
    log_level: str = "WARNING",
    verbose: bool = False,
)
```

| Parameter | Default | Description |
|---|---|---|
| `r_executable` | `None` | Path to `Rscript`. Auto-detected from `PATH` if omitted. |
| `startup_timeout` | `15.0` | Seconds to wait for R's ready signal before raising `RStartupError`. |
| `call_timeout` | `60.0` | Per-call timeout in seconds. Override per-call with the `timeout=` argument. |
| `env` | `{}` | Extra environment variables passed to the R subprocess. |
| `r_libs` | `[]` | Paths prepended to `R_LIBS_USER` so R can find your packages. |
| `log_level` | `"WARNING"` | Python logging level for the `r_bridge` logger. |
| `verbose` | `False` | Print all R calls and R output to `sys.stderr` in real time. |

### Lifecycle

```python
r.start() -> RBridge    # start the R subprocess; returns self
r.stop(timeout=5.0)     # graceful shutdown; kills after timeout
r.is_alive() -> bool    # True if the R process is running
```

`RBridge` is a context manager: `__enter__` calls `start()`, `__exit__` calls `stop()`.

### Attribute access (primary interface)

```python
r.name = value      # serialise value and assign to R global env
value  = r.name     # fetch variable from R global env
r.func(...)         # call R function; returns deserialised result
```

`__getattr__` checks R's global environment first. If the name is not a variable
it returns a callable `_RFuncProxy`. If it is a variable it returns its value.

### Explicit methods

Use these when you need per-call control over timeouts or type hints, or when a
variable name clashes with a Python attribute.

---

#### `set(name, value, /, *, type_hint=None)`

Assign a Python value to a named variable in R's global environment.

```python
r.set("x", 42)
r.set("df", my_dataframe)
```

---

#### `get(name, *, result_type_hint=None) -> Any`

Fetch a variable from R's global environment.

```python
val = r.get("x")
arr = r.get("v", result_type_hint="numpy")
```

---

#### `call(func, /, *args, result_type_hint=None, timeout=None, **kwargs) -> Any`

Call an R function with positional and/or keyword arguments.

```python
r.call("mean", [1, 2, 3])
r.call("seq", 1, 10, by=2)
r.call("Sys.sleep", 30, timeout=60.0)
```

---

#### `execute(code, /, *, timeout=None) -> None`

Execute an R script string in the global environment. The return value is
always discarded. Use this for multi-line scripts, function definitions, or
any code where side-effects matter and the return value does not.

```python
r.execute("""
square <- function(x) x ^ 2
cube   <- function(x) x ^ 3
""")
print(r.square(4.0))   # 16.0
print(r.cube(3.0))     # 27.0
```

---

#### `eval(expr, /, *, result_type_hint=None, timeout=None) -> Any`

Evaluate an arbitrary R expression in R's global environment.

```python
r.eval("x <- 2 ^ 8")
result = r.eval("mean(c(1, 2, 3))", result_type_hint="scalar")
```

---

#### `ls() -> list[str]`

List all names in R's global environment.

```python
print(r.ls())   # ['x', 'df', 'model', ...]
```

---

#### `ping() -> float`

Send a no-op request and return the round-trip latency in seconds.

```python
print(r.ping())   # e.g. 0.002
```

---

#### `last_stderr -> str` (property)

Return all text accumulated on R's stderr since the bridge started.

```python
print(r.last_stderr)
```

---

### `result_type_hint` values

Controls how the R return value is deserialised into Python.

| Value | Result type |
|---|---|
| `None` | Default heuristic (scalars → scalar, vectors → `numpy.ndarray`, etc.) |
| `"scalar"` | First element as a Python scalar (`int`, `float`, `bool`, or `str`) |
| `"numpy"` | `numpy.ndarray` |
| `"pandas"` | `pandas.Series` or `pandas.DataFrame` |
| `"list"` | Python `list` |
| `"raw"` | The raw tagged JSON `dict` — no deserialisation |

---

## Module-level helpers

### `start_bridge(**kwargs) -> RBridge`

Convenience function: create and start a bridge in one call.

```python
from r_bridge import start_bridge

r = start_bridge(verbose=True)
```

### `register_serializer(python_type, fn)`

Register a custom Python → R converter. See [Advanced](advanced.md).

### `register_deserializer(r_tag, fn)`

Register a custom R → Python converter. See [Advanced](advanced.md).
