Mounter

Mounts directories as static files for serving through the web server.

DirectoryMounter

Mounts directories for static file serving with instance-level state. Uses Starlette’s StaticFiles middleware for efficient serving with proper MIME types, caching headers, and range request support.


DirectoryMounter


def DirectoryMounter(
    
):

Mounts directories for static file serving with instance-level state.


DirectoryMounter.mount


def mount(
    app, # FastHTML/Starlette application instance
    directories:List, # List of directory paths to mount
)->None:

Mount directories to app for static file serving.


DirectoryMounter.get_url


def get_url(
    file_path:str, # Full path to the file
)->Optional: # URL to access the file, or None if not in a mounted directory

Get URL for a file based on mounted directories.


DirectoryMounter.is_mounted


def is_mounted(
    directory:str, # Directory path to check
)->bool: # True if the directory is mounted

Check if a directory is currently mounted.


DirectoryMounter.get_mounted_directories


def get_mounted_directories(
    
)->List: # List of mounted directory paths

Get list of currently mounted directories.


DirectoryMounter.unmount_all


def unmount_all(
    
)->None:

Remove all mounts from this instance.


DirectoryMounter.create_url_getter


def create_url_getter(
    
)->callable: # Function that converts path to URL

Create a URL getter function for use with gallery components.

Tests

import tempfile

# Simple mock app for testing
class MockApp:
    def __init__(self):
        self.routes = []

# Test DirectoryMounter initialization
mounter = DirectoryMounter()
assert mounter._mounted == {}
assert mounter._app is None
assert mounter.ROUTE_PREFIX_PATTERN == "mg_static_"

print("DirectoryMounter initialization tests passed!")
DirectoryMounter initialization tests passed!
# Test prefix generation
mounter = DirectoryMounter()
prefix = mounter._generate_prefix("/some/path")
assert prefix.startswith("mg_static_")
assert len(prefix) == len("mg_static_") + 8  # 8 char hash

# Same path should give same prefix
prefix2 = mounter._generate_prefix("/some/path")
assert prefix == prefix2

# Different path should give different prefix
prefix3 = mounter._generate_prefix("/other/path")
assert prefix3 != prefix

print("Prefix generation tests passed!")
Prefix generation tests passed!
# Test mounting directories
with tempfile.TemporaryDirectory() as tmpdir:
    # Create test structure
    subdir = Path(tmpdir) / "media"
    subdir.mkdir()
    test_file = subdir / "video.mp4"
    test_file.write_text("test content")
    
    app = MockApp()
    mounter = DirectoryMounter()
    
    # Mount directory
    mounter.mount(app, [str(subdir)])
    
    # Verify mount was added to app routes
    assert len(app.routes) == 1
    assert isinstance(app.routes[0], Mount)
    assert app.routes[0].path.startswith("/mg_static_")
    
    # Verify internal state
    assert mounter.is_mounted(str(subdir))
    assert str(subdir) in mounter.get_mounted_directories()
    
    # Test get_url
    url = mounter.get_url(str(test_file))
    assert url is not None
    assert url.startswith("/mg_static_")
    assert "video.mp4" in url
    
    # File not in mount should return None
    other_file = Path(tmpdir) / "other.txt"
    other_file.write_text("other")
    assert mounter.get_url(str(other_file)) is None

print("Mount and URL tests passed!")
Mount and URL tests passed!
# Test multiple mounts and unmount_all
with tempfile.TemporaryDirectory() as tmpdir:
    dir1 = Path(tmpdir) / "dir1"
    dir2 = Path(tmpdir) / "dir2"
    dir1.mkdir()
    dir2.mkdir()
    
    app = MockApp()
    mounter = DirectoryMounter()
    
    # Mount multiple directories
    mounter.mount(app, [str(dir1), str(dir2)])
    assert len(app.routes) == 2
    assert len(mounter.get_mounted_directories()) == 2
    
    # Unmount all
    mounter.unmount_all()
    assert len(app.routes) == 0
    assert len(mounter.get_mounted_directories()) == 0

print("Multiple mounts and unmount tests passed!")
Multiple mounts and unmount tests passed!
# Test remounting clears old mounts
with tempfile.TemporaryDirectory() as tmpdir:
    dir1 = Path(tmpdir) / "dir1"
    dir2 = Path(tmpdir) / "dir2"
    dir1.mkdir()
    dir2.mkdir()
    
    app = MockApp()
    mounter = DirectoryMounter()
    
    # First mount
    mounter.mount(app, [str(dir1)])
    assert len(app.routes) == 1
    assert mounter.is_mounted(str(dir1))
    
    # Remount with different directory - should clear old mount
    mounter.mount(app, [str(dir2)])
    assert len(app.routes) == 1  # Old mount removed, new one added
    assert not mounter.is_mounted(str(dir1))
    assert mounter.is_mounted(str(dir2))

print("Remount cleanup tests passed!")
Remount cleanup tests passed!
# Test URL generation for nested files
with tempfile.TemporaryDirectory() as tmpdir:
    # Create nested structure
    nested = Path(tmpdir) / "media" / "videos" / "2024"
    nested.mkdir(parents=True)
    test_file = nested / "clip.mp4"
    test_file.write_text("test")
    
    app = MockApp()
    mounter = DirectoryMounter()
    mounter.mount(app, [str(Path(tmpdir) / "media")])
    
    # URL should include full relative path
    url = mounter.get_url(str(test_file))
    assert url is not None
    assert "videos/2024/clip.mp4" in url

print("Nested file URL tests passed!")
Nested file URL tests passed!
# Test create_url_getter
with tempfile.TemporaryDirectory() as tmpdir:
    subdir = Path(tmpdir) / "media"
    subdir.mkdir()
    (subdir / "video.mp4").write_text("test")
    
    app = MockApp()
    mounter = DirectoryMounter()
    mounter.mount(app, [str(subdir)])
    
    # Create getter function
    get_url = mounter.create_url_getter()
    
    # Test getter
    url = get_url(str(subdir / "video.mp4"))
    assert url is not None
    assert "video.mp4" in url
    
    # Test file not in mount
    assert get_url("/some/other/path.txt") is None

print("create_url_getter tests passed!")
create_url_getter tests passed!