microsoft / microsoft/agent-framework

Python: Manipulating Static Files for DevUI

Open
#2,581 0 comments 0 reactions 1 assignee Claimed by @victordibia View on GitHub
devui python question
Dominant language
Python
Stars
13.6k
Forks
2.3k
Avg merge
2d 45m
Merged PRs (30d)
358

Description

```python

def _materialize_devui_assets() -> None:

"""Ensure DevUI static assets are real files when uv installs symlinks."""

ui_dir = pathlib.Path(agent_framework_devui.__file__).parent / "ui"

if not ui_dir.exists():

return

copied_assets = False

for asset in ui_dir.rglob("*"):

if not asset.is_symlink():

continue

try:

target = asset.resolve(strict=True)

except FileNotFoundError:

# Remove broken symlink so FastAPI does not expose stale paths.

asset.unlink(missing_ok=True)

print(f"⚠️ Removed broken DevUI asset symlink: {asset}")

continue

asset.unlink()

try:

if target.is_dir():

shutil.copytree(target, asset)

else:

asset.write_bytes(target.read_bytes())

copied_assets = True

except OSError as exc:

print(f"❌ Failed to materialize DevUI asset {asset}: {exc}")

if copied_assets:

print("🔁 Materialized DevUI static assets to satisfy FastAPI security checks")
```

The Problem When you ran DevUI, the server started successfully (the docs FastAPI endpoint worked), but accessing the root URL / returned {"detail":"Not Found"} instead of the DevUI web interface.

Root Cause UV package manager installs wheel contents as symlinks pointing to a cache directory (/home/vscode/.cache/uv/archive-v0/...). This means files like:

index.html /intelligent_orchestrator/.venv/.../agent_framework_devui/ui/assets/index.js ...were all symlinks to files outside the mounted directory.

FastAPI's StaticFiles has a security check that uses os.path.realpath() to prevent path-traversal attacks. When it resolved the symlink's real path, it found the file was outside the mounted directory (/home/vscode/.cache/... vs /intelligent_orchestrator/.venv/...). The os.path.commonpath() check failed, so FastAPI refused to serve the file and returned 404.

The attempted solution _materialize_devui_assets() walks the agent_framework_devui/ui directory tree and:

Finds any symlinked files or directories

Resolves them to their real target path

Replaces the symlink with the actual file content (or directory copy)

Now FastAPI's realpath check passes because files are inside the mount

Without materializing assets:

DevUI backend API works fine (/health, /v1/entities, etc.)

DevUI frontend fails to load (404 on /, index.html, /assets/index.js)

Users see {"detail":"Not Found"} instead of the UI

The helper is idempotent (safe to run multiple times) and only processes symlinks, so subsequent runs are fast. It's called once at startup before serve() to ensure the UI can load properly.

We really shouldn't be modifying the contents of site-packages (or anything within the .venv folder) outside of uv operations so this is not a sustainable solution. At least if the starlette option works it should leave those folders alone, so may be worth trying.

The underlying issue seems to be the way that devui assets are being packaged, so this should go back to AF PG to solve more permanently -- it should be a very common pattern where users are using uv and want to serve via fastAPI, so this isn't just an LSEG thing.

[shared with you the preview of the points raised for any feedback you may already have on this]

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.