API Server
The Penguin API Server provides a web-based interface for interacting with Penguin, enabling both programmatic access and a browser-based user interface.
Architecture
Server Initialization
The API server is built using FastAPI and initializes the core components using a factory pattern with reusable core instances:
def create_app() -> FastAPI:
"""Create and configure the FastAPI application."""
app = FastAPI(
title="Penguin",
description="Coding agent with reasoning, memory, and tool use capabilities",
version=__version__,
docs_url="/api/docs",
redoc_url="/api/redoc"
)
# Configure CORS with environment-based origins
origins_env = os.getenv("PENGUIN_CORS_ORIGINS", "").strip()
origins_list = [o.strip() for o in origins_env.split(",") if o.strip()] or [
"http://localhost:8000",
"http://127.0.0.1:8000",
"http://localhost:9000",
"http://127.0.0.1:9000",
]
app.add_middleware(
CORSMiddleware,
allow_origins=origins_list,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Initialize or reuse core instance
core = get_or_create_core()
router.core = core
github_webhook_router.core = core
# Include API routes
app.include_router(router)
app.include_router(github_webhook_router)
# Mount static files for web UI
static_dir = Path(__file__).parent / "static"
if static_dir.exists():
app.mount("/static", StaticFiles(directory=str(static_dir)), name="static")
return app
Startup and CORS Hardening
Current server behavior is slightly stricter than older examples on this page:
- if
PENGUIN_CORS_ORIGINSis unset, Penguin now uses a small localhost-only development allowlist instead of"*" - if the server binds to a non-local interface such as
0.0.0.0while auth is disabled, startup is blocked unlessPENGUIN_ALLOW_INSECURE_NO_AUTH=trueis set explicitly
That startup check exists to reduce accidental exposure of an unauthenticated development server.
Core Instance Management
The server uses a global core instance pattern for efficient resource usage:
_core_instance: Optional[PenguinCore] = None
def get_or_create_core() -> PenguinCore:
"""Get the global core instance or create it if it doesn't exist."""
global _core_instance
if _core_instance is None:
_core_instance = _create_core()
return _core_instance