# How Modly Handles Workspace Filesystem Persistence in lightningpixel/modly

> Modly ensures workspace filesystem persistence by saving meshes textures and assets to a configurable local directory configurable via environment variable or REST API

- Repository: [lightningpixel/modly](https://github.com/lightningpixel/modly)
- Tags: how-to-guide
- Published: 2026-08-15

---

**Modly persists every generated mesh, texture, and intermediate asset to a configurable local directory (defaulting to `~/.modly/workspace`), with the storage location determined at startup by the `WORKSPACE_DIR` environment variable and adjustable at runtime via a REST API.**

The lightningpixel/modly repository implements workspace filesystem persistence as the backbone for asset storage, ensuring that workflows, generated meshes, and textures remain available across server restarts. By treating the workspace as a standard directory on the host filesystem, Modly enables direct access for backup, version control, and external tool integration without requiring database storage.

## Initializing the Workspace Directory

When the Modly server starts, the **workspace directory** is established in [`services/generator_registry.py`](https://github.com/lightningpixel/modly/blob/main/services/generator_registry.py) at lines 24‑27. The code reads the `WORKSPACE_DIR` environment variable and falls back to `~/.modly/workspace` if the variable is unset.

```python

# Conceptual implementation from services/generator_registry.py

import os
from pathlib import Path

WORKSPACE_DIR = Path(os.getenv("WORKSPACE_DIR", "~/.modly/workspace")).expanduser()
WORKSPACE_DIR.mkdir(parents=True, exist_ok=True)

```

This initialization executes when the `GeneratorRegistry` module is imported, ensuring the directory exists before any generator attempts to write files. Individual generators receive this `WORKSPACE_DIR` path object in their constructor (e.g., `BaseGenerator(..., WORKSPACE_DIR)`) and write outputs under this root. Additionally, [`api/runner.py`](https://github.com/lightningpixel/modly/blob/main/api/runner.py) at line 32 propagates this same environment variable to generator subprocesses, guaranteeing that extensions write to the same persistent location.

## Runtime Configuration via the Settings API

Modly allows administrators to change the workspace filesystem persistence target without restarting the server. The [`api/routers/settings.py`](https://github.com/lightningpixel/modly/blob/main/api/routers/settings.py) file implements this through two endpoints at lines 21‑26 and 29‑38.

- **GET /settings/paths** returns the current `workspace_dir` along with other configurable paths.
- **POST /settings/paths** accepts a JSON payload to update `workspace_dir`, immediately redirecting future file operations to the new location.

```python
import requests

# Retrieve current workspace configuration

resp = requests.get("http://localhost:8765/settings/paths")
print(resp.json()["workspace_dir"])  # Output: /home/user/.modly/workspace

# Relocate workspace to a new directory

resp = requests.post(
    "http://localhost:8765/settings/paths",
    json={"workspace_dir": "/mnt/fast-storage/modly-workspace"}
)
print(resp.json())  # Confirms new workspace_dir path

```

Existing files remain in their original location after a path change; only new generations target the updated directory.

## Serving Files Directly from the Workspace

The FastAPI application in [`api/main.py`](https://github.com/lightningpixel/modly/blob/main/api/main.py) (lines 58‑65) exposes workspace content through the route `GET /workspace/{full_path}`. This handler resolves the request path relative to the global `WORKSPACE_DIR` and streams the file bytes to the client.

```python
import requests

# Access a generated mesh directly

url = "http://localhost:8765/workspace/Workflows/robot.glb"
response = requests.get(url)
if response.status_code == 200:
    with open("robot.glb", "wb") as f:
        f.write(response.content)

```

Because the server resolves paths at request time, assets become immediately available after generation without requiring a restart. This design treats workspace filesystem persistence as a live mirror of the server's output state.

## Security: Path Validation and Traversal Prevention

To prevent directory-traversal attacks, every public endpoint that accepts a workspace-relative path runs through the `_validate_workspace_path` function defined in [`tools/modly-cli/agent.py`](https://github.com/lightningpixel/modly/blob/main/tools/modly-cli/agent.py) at lines 45‑55 and 145‑157. This validator rejects:

- Absolute paths starting with `/` or Windows drive letters
- URL schemes such as `http://` or `file://`
- Parent directory references using `..`

Only files strictly within the workspace directory are accessible.

```python

# Conceptual validation logic from tools/modly-cli/agent.py

def _validate_workspace_path(path: str) -> str:
    if path.startswith('/') or '..' in path or ':' in path:
        raise ValueError("Invalid workspace path")
    return path

```

This security boundary ensures that even if a malicious client crafts a request to `/workspace/../../../etc/passwd`, the server rejects the path before touching the filesystem.

## Export Workflow and CLI Integration

The Modly CLI ([`tools/modly-cli/agent.py`](https://github.com/lightningpixel/modly/blob/main/tools/modly-cli/agent.py)) provides a convenient export mechanism that relies on the same workspace filesystem persistence layer. When a user executes `modly export`, the CLI:

1. Validates the workspace-relative path using `_validate_workspace_path`.
2. Constructs an export URL targeting `/export/<fmt>?path=<workspace_path>`.
3. Streams the file from the server's workspace to the client's destination folder.

```bash

# CLI command that interacts with workspace persistence

modly export --format glb --path "Workflows/robot.glb" --output robot.glb

```

Internally, this builds a request to `http://127.0.0.1:8765/export/glb?path=Workflows%2Frobot.glb`, which the server validates and serves from `WORKSPACE_DIR`, guaranteeing the client receives the exact on-disk file.

## Summary

- **Default Location**: Modly stores assets in `~/.modly/workspace`, configurable via the `WORKSPACE_DIR` environment variable defined in [`services/generator_registry.py`](https://github.com/lightningpixel/modly/blob/main/services/generator_registry.py).
- **Runtime Updates**: The Settings API ([`api/routers/settings.py`](https://github.com/lightningpixel/modly/blob/main/api/routers/settings.py)) allows changing the workspace directory without restarting the server.
- **Direct Access**: The `/workspace/{full_path}` endpoint in [`api/main.py`](https://github.com/lightningpixel/modly/blob/main/api/main.py) serves files directly from the persistent directory.
- **Security**: Path validation in [`tools/modly-cli/agent.py`](https://github.com/lightningpixel/modly/blob/main/tools/modly-cli/agent.py) prevents directory traversal by rejecting absolute paths and parent directory references.
- **CLI Export**: The `modly` CLI leverages the workspace filesystem persistence layer to validate and download generated assets.

## Frequently Asked Questions

### How does Modly determine where to store generated files?

Modly determines the storage location by reading the `WORKSPACE_DIR` environment variable at startup. If the variable is unset, it defaults to `~/.modly/workspace`. This logic resides in [`services/generator_registry.py`](https://github.com/lightningpixel/modly/blob/main/services/generator_registry.py) at lines 24‑27, where the code also creates the directory using `mkdir(parents=True, exist_ok=True)` if it does not exist.

### Can I change the workspace directory while the server is running?

Yes. The Settings API exposed in [`api/routers/settings.py`](https://github.com/lightningpixel/modly/blob/main/api/routers/settings.py) (lines 21‑38) allows you to update the workspace path via a POST request to `/settings/paths`. The server immediately uses the new path for subsequent file operations, though previously generated files remain in their original location unless manually moved.

### How does Modly prevent access to files outside the workspace?

All endpoints that accept file paths utilize the `_validate_workspace_path` function found in [`tools/modly-cli/agent.py`](https://github.com/lightningpixel/modly/blob/main/tools/modly-cli/agent.py) (lines 45‑55 and 145‑157). This function rejects absolute paths, Windows drive letters, URL schemes, and any `..` components, ensuring that only files within the designated workspace directory are accessible or exportable.

### Is workspace storage persistent across server restarts?

Yes. Because `WORKSPACE_DIR` points to a standard directory on the host filesystem rather than a temporary location, all files written by generators survive server restarts. The directory is created once during the initial import of `GeneratorRegistry` and persists indefinitely, allowing users to back up or version control their assets using standard filesystem tools.