44from textwrap import dedent
55from typing import Any , Callable , Dict , List , Union
66
7- from pydantic import create_model
8-
97
108# --- Optional Server Dependencies ---
119try :
10+ from pydantic import create_model
1211 from fastapi import FastAPI , APIRouter , Request , Response
13- from fastapi .responses import HTMLResponse
12+ from fastapi .responses import HTMLResponse , FileResponse
1413 from fastapi .staticfiles import StaticFiles
1514 import uvicorn
1615
1716 HAS_SERVER = True
17+
1818except ImportError :
19- HAS_SERVER = False
20- # Dummy classes for type hinting
21- FastAPI = object # type: ignore
22- APIRouter = object # type: ignore
23- Request = object # type: ignore
24- Response = object # type: ignore
19+ raise ImportError (
20+ "Violetear Server dependencies are missing. "
21+ "Please install them with: uv add --extra server 'fastapi[standard]'"
22+ )
2523
2624
2725from .stylesheet import StyleSheet
@@ -34,16 +32,20 @@ class App:
3432 Wraps FastAPI to provide a full-stack Python web framework experience.
3533 """
3634
37- def __init__ (self , title : str = "Violetear App" ):
38- if not HAS_SERVER :
39- raise ImportError (
40- "Violetear Server dependencies are missing. "
41- "Please install them with: uv add --extra server 'fastapi[standard]'"
42- )
43-
35+ def __init__ (self , title : str = "Violetear App" , favicon : str | None = None ):
4436 self .title = title
4537 self .api = FastAPI (title = title )
4638
39+ if favicon is None :
40+ favicon = str (Path (__file__ ).parent / "icon.png" )
41+
42+ self .favicon = favicon
43+
44+ # Standard path for browser favicon requests
45+ @self .api .get ("/favicon.ico" , include_in_schema = False )
46+ async def favicon ():
47+ return FileResponse (self .favicon )
48+
4749 # Registry of served styles to prevent duplicate route registration
4850 self .served_styles : Dict [str , StyleSheet ] = {}
4951
0 commit comments